ESP32 WiFiClientSecure Library – println

Home / References / ESP32 Library / WiFiClientSecure

Description

The println method in the WiFiClientSecure library sends data over a secure TLS/SSL connection to a remote server, automatically appending a newline character (\r\n). Inherited from the Print class, this method simplifies the process of sending formatted lines, making it ideal for constructing HTTP requests or transmitting structured data securely.


Syntax and Usage

The println method can be used with or without arguments, depending on your needs. Below are the common usages:

  • Without Arguments: Sends a newline sequence (\r\n), often used to terminate HTTP headers or separate data lines.
  • With a String Argument: Sends a string followed by a newline, perfect for sending HTTP request lines or headers.
  • With a Numeric Argument: Sends a number as a string followed by a newline, useful for transmitting data like sensor values.

For practical applications and examples of this method, please consult the “Example Code” section on this page. This section provides comprehensive guidance to help you better understand and apply the method effectively.


Argument(s)

The println method can accept an optional argument to specify the data to send. Here are the details:

  • data (optional): The data to be printed, followed by a newline (\r\n). This can be a string, integer, float, or any printable type supported by the Print class. If omitted, only the newline sequence is sent.

Return Value

The println method returns an integer representing the number of bytes written to the secure connection, including the newline characters. If the operation fails (e.g., due to a disconnected client), it returns 0. This return value helps confirm successful data transmission.


Example Codes

Below are example codes demonstrating each usage of the println method from the “Syntax and Usage” section. These examples are practical, reusable, and tailored for ESP32 enthusiasts exploring secure communication.

This example demonstrates sending an HTTP GET request using println with string arguments to build a complete request with headers.

ATTENTION: The Root CA certificate has an expiration date. If this code fails to execute, acquire the most up-to-date Root CA certificate. To find out more details about how to acquire the Root CA certificate of www.httpbin.org, please check out this link below:
How to Acquire the Root CA Certificate

/*
 * Author: Avant Maker
 * Date: February 24, 2025
 * Version: 1.0
 *
 * Description: This example demonstrates sending
 * an HTTP POST request using ESP32 WiFiClientSecure Library's 
 * println method.
 * 
 * ATTENTION: The Root CA certificate has an expiration date.
 * If this code fails to execute, acquire the most up-to-date
 * Root CA certificate.
 * To find out more details about how to acquire the Root CA
 * certificate of www.httpbin.org, please check out this link below:
 *
 * https://avantmaker.com/references/esp32-arduino-core-index/esp32-wificlientsecure-library/how-to-acquire-the-root-ca-certificate/
 *
 * License: MIT 
 * 
 * Code Source: This example code is sourced from the Comprehensive 
 * Guide to the ESP32 Arduino Core Library, accessible on 
 * AvantMaker.com. For additional code examples and in-depth 
 * documentation related to the ESP32 Arduino Core Library, 
 * please visit:
 *
 * https://avantmaker.com/references/esp32-arduino-core-index/
 *
 * AvantMaker.com, your premier destination for all things 
 * DIY, AI, IoT, Smart Home, and STEM projects. We are dedicated 
 * to empowering makers, learners, and enthusiasts with the resources
 * they need to bring their innovative ideas to life.
 */


#include <WiFi.h>
#include <NetworkClientSecure.h>

// const char* ssid = "your-SSID";          // Replace with your Wi-Fi SSID
// const char* password = "your-PASSWORD"; // Replace with your Wi-Fi password
const char* ssid = "Your-WiFi-SSID";          // Replace with your Wi-Fi SSID
const char* password = "Your-WiFi-Password"; // Replace with your Wi-Fi password
const char* host = "www.httpbin.org";
const int port = 443;

// Root CA certificate for www.httpbin.org (update with your server's CA if different)
const char* rootCACert = R"literal(
-----BEGIN CERTIFICATE-----
MIIEXjCCA0agAwIBAgITB3MSSkvL1E7HtTvq8ZSELToPoTANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjUzMFoXDTMwMDgyMzIyMjUzMFowPDEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT
QSAyMDQ4IE0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtDGMZa
qHneKei1by6+pUPPLljTB143Si6VpEWPc6mSkFhZb/6qrkZyoHlQLbDYnI2D7hD0
sdzEqfnuAjIsuXQLG3A8TvX6V3oFNBFVe8NlLJHvBseKY88saLwufxkZVwk74g4n
WlNMXzla9Y5F3wwRHwMVH443xGz6UtGSZSqQ94eFx5X7Tlqt8whi8qCaKdZ5rNak
+r9nUThOeClqFd4oXych//Rc7Y0eX1KNWHYSI1Nk31mYgiK3JvH063g+K9tHA63Z
eTgKgndlh+WI+zv7i44HepRZjA1FYwYZ9Vv/9UkC5Yz8/yU65fgjaE+wVHM4e/Yy
C2osrPWE7gJ+dXMCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD
VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV
HQ4EFgQUwDFSzVpQw4J8dHHOy+mc+XrrguIwHwYDVR0jBBgwFoAUhBjMhTTsvAyU
lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v
b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov
L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E
ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv
b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB
AQAtTi6Fs0Azfi+iwm7jrz+CSxHH+uHl7Law3MQSXVtR8RV53PtR6r/6gNpqlzdo
Zq4FKbADi1v9Bun8RY8D51uedRfjsbeodizeBB8nXmeyD33Ep7VATj4ozcd31YFV
fgRhvTSxNrrTlNpWkUk0m3BMPv8sg381HhA6uEYokE5q9uws/3YkKqRiEz3TsaWm
JqIRZhMbgAfp7O7FUwFIb7UIspogZSKxPIWJpxiPo3TcBambbVtQOcNRWz5qCQdD
slI2yayq0n2TXoHyNCLEH8rpsJRVILFsg0jc7BaFrMnF462+ajSehgj12IidNeRN
4zl+EoNaWdpnWndvSpAEkq2P
-----END CERTIFICATE-----
)literal";

// Optional: Add client certificate and key for mutual TLS if needed
// const char* clientCertKey = "";
// const char* clientCert = "";

NetworkClientSecure secureClient;

void setup() {
    Serial.begin(115200);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("Connected to WiFi");

    // set ROOT CA Cert
    secureClient.setCACert(rootCACert);

    if (secureClient.connect(host, port)) {
        Serial.println("Connected to server");
        String postData = "AvantMaker=HelloFromESP32";
        secureClient.println("POST /post HTTP/1.1");
        secureClient.println("Host: www.httpbin.org");
        secureClient.println("Content-Type: application/x-www-form-urlencoded");
        secureClient.print("Content-Length: ");
        secureClient.print(postData.length());
        secureClient.print("\r\nConnection: close\r\n\r\n");
        secureClient.print(postData);
    } else {
        Serial.println("Failed to connect to server! Check the code description for solution.");
        return;
    }    
}

void loop() {
    while (secureClient.available()) {
        int byte = secureClient.read(); // Read one byte
        if (byte != -1) {
            Serial.write(byte);   // Print the byte as a character
        }
    }
    if (!secureClient.connected()) {
        secureClient.stop();
        while (true); // Stop after disconnect
    }
}

Understanding Example Code Output from ESP32

When you run the Example Code on your ESP32 and it successfully connects to www.howsmyssl.com, the Serial Monitor will display detailed information about the secure connection.

To help you understand the example code, the following is a breakdown of the Serial Monitor output when you run this code on an ESP32:

This output is a JSON response from the server’s endpoint https://www.howsmyssl.com/a/check, which provides details about the TLS connection established by your ESP32. We’ll explain each key component in a clear manner below.

Serial Monitor Output Recap

Upon successful execution of the code on your ESP32 board, the Serial Monitor should display the following output:

Connected to WiFi
Connected to server!
Headers received
{
  "given_cipher_suites": [
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CCM",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8",
    "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384",
    "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384",
    "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384",
    "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384",
    "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384",
    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_128_CCM",
    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8",
    "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256",
    "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256",
    "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256",
    "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256",
    "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256",
    "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256",
    "TLS_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_RSA_WITH_AES_256_CCM",
    "TLS_RSA_WITH_AES_256_CBC_SHA256",
    "TLS_RSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
    "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
    "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
    "TLS_RSA_WITH_AES_256_CCM_8",
    "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384",
    "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256",
    "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA",
    "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384",
    "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384",
    "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384",
    "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384",
    "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384",
    "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384",
    "TLS_RSA_WITH_ARIA_256_GCM_SHA384",
    "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384",
    "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384",
    "TLS_RSA_WITH_ARIA_256_CBC_SHA384",
    "TLS_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_RSA_WITH_AES_128_CCM",
    "TLS_RSA_WITH_AES_128_CBC_SHA256",
    "TLS_RSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
    "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
    "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
    "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
    "TLS_RSA_WITH_AES_128_CCM_8",
    "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256",
    "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256",
    "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA",
    "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256",
    "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256",
    "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256",
    "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256",
    "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256",
    "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256",
    "TLS_RSA_WITH_ARIA_128_GCM_SHA256",
    "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256",
    "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256",
    "TLS_RSA_WITH_ARIA_128_CBC_SHA256",
    "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"
  ],
  "ephemeral_keys_supported": true,
  "session_ticket_supported": true,
  "tls_compression_supported": false,
  "unknown_cipher_suite_supported": false,
  "beast_vuln": false,
  "able_to_detect_n_minus_one_splitting": false,
  "insecure_cipher_suites": {},
  "tls_version": "TLS 1.2",
  "rating": "Probably Okay"
}
Connection closed

This is the response from www.howsmyssl.com/a/check, followed by a message from your code indicating the connection has ended.

What Does This Mean for Your ESP32 Project?

  • Security: Your ESP32 established a secure TLS 1.2 connection with www.howsmyssl.com using a modern, safe cipher suite (likely one with ECDHE and AES_GCM based on the list). The lack of insecure cipher suites and vulnerabilities like BEAST ensures it’s suitable for IoT demos.
  • Functionality: The support for ephemeral keys and session tickets enhances security and efficiency, making this a good example for AvantMaker.com’s audience of makers and learners.
  • Purpose: This output validates that your code (and the Root CA certificate) worked correctly to authenticate and communicate with the server, a key step in IoT projects requiring HTTPS.

Explanation of the JSON Response

The JSON object contains several fields that describe the TLS capabilities and security status of the connection as seen by the server. Here’s what each field means:

  1. "given_cipher_suites"
    • Value: A list of cipher suites supported by your ESP32 client (e.g., "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", etc., ending with "TLS_EMPTY_RENEGOTIATION_INFO_SCSV").
    • Meaning: These are the cryptographic algorithms your ESP32 offered to the server for securing the connection. Each cipher suite defines:
      • Key Exchange: How the encryption keys are shared (e.g., ECDHE for Ephemeral Elliptic Curve Diffie-Hellman, RSA for RSA key exchange).
      • Authentication: How the server proves its identity (e.g., ECDSA or RSA).
      • Encryption: The symmetric encryption algorithm (e.g., AES_256_GCMCAMELLIA_128_CBC).
      • Integrity: The hash function for data integrity (e.g., SHA384SHA256).
    • Example Breakdown:
      • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: Uses ECDHE for key exchange, ECDSA for authentication, AES-256 in GCM mode for encryption, and SHA-384 for integrity.
      • TLS_EMPTY_RENEGOTIATION_INFO_SCSV: A pseudo-cipher suite signaling support for secure renegotiation, not an actual encryption method.
    • Significance: The server selects one of these for the connection. The list shows your ESP32’s TLS capabilities via the NetworkClientSecure library.
  2. "ephemeral_keys_supported": true
    • Meaning: Indicates that your ESP32 supports ephemeral key exchange (e.g., ECDHE or DHE), which provides Forward Secrecy. This means that even if a private key is compromised later, past session data remains secure because the session keys are temporary.
    • Significance: This is a strong security feature, ensuring robust protection for IoT applications.
  3. "session_ticket_supported": true
    • Meaning: Your ESP32 supports TLS session tickets, a mechanism for resuming previous TLS sessions without a full handshake, improving performance.
    • Significance: Useful for IoT devices like the ESP32 to reduce connection overhead in repeated communications.
  4. "tls_compression_supported": false
    • Meaning: Your ESP32 does not support TLS compression.
    • Significance: Compression is disabled by default in modern TLS implementations due to security vulnerabilities like the CRIME attack. This is a good security practice.
  5. "unknown_cipher_suite_supported": false
    • Meaning: No unrecognized or unsupported cipher suites were offered by your ESP32.
    • Significance: Ensures compatibility and clarity in the TLS handshake process.
  6. "beast_vuln": false
    • Meaning: Your connection is not vulnerable to the BEAST (Browser Exploit Against SSL/TLS) attack, which affects CBC-based cipher suites in TLS 1.0.
    • Significance: Since you’re using TLS 1.2 (see below) and likely a secure cipher suite, this vulnerability doesn’t apply.
  7. "able_to_detect_n_minus_one_splitting": false
    • Meaning: Indicates whether the client can detect a specific mitigation technique for BEAST-like attacks (N-1 splitting). Since it’s false, your ESP32 doesn’t signal this capability.
    • Significance: This is less relevant with TLS 1.2 and modern cipher suites, so it’s not a concern here.
  8. "insecure_cipher_suites": {}
    • Meaning: An empty object means no insecure cipher suites were detected in your ESP32’s offered list.
    • Significance: Confirms that your configuration avoids weak or deprecated cryptography, enhancing security for your projects.
  9. "tls_version": "TLS 1.2"
    • Meaning: The TLS protocol version negotiated between your ESP32 and the server is TLS 1.2.
    • Significance: TLS 1.2 is widely supported and secure (though TLS 1.3 is the latest standard). The ESP32’s NetworkClientSecure library defaults to TLS 1.2, which is suitable for most IoT applications as of March 2025.
  10. "rating": "Probably Okay"
    • Meaning: The server’s overall assessment of your TLS configuration. “Probably Okay” indicates a secure setup with no major issues, though it might not be the absolute strongest possible (e.g., lacking TLS 1.3).
    • Significance: Your ESP32’s TLS setup is functional and safe for demo purposes, aligning with AvantMaker.com’s goal of empowering makers with practical examples.
  11. Connection closed
    • Meaning: This is a timestamp and message from your ESP32 code (added in performSecureRequest()), indicating that the TLS connection was successfully terminated after receiving the response.
    • Significance: Confirms the code executed as expected, closing the connection cleanly.

ESP32 Library Index

ESP32 Arduino Core Library


FAQ

Ready to experiment and explore more about ESP32? Visit our website’s All About ESP32 Resources Hub, packed with tutorials, guides, and tools to inspire your maker journey. Experiment, explore, and elevate your skills with everything you need to master this powerful microcontroller platform!

error: Content is protected !!