Hello world example of a TLS client: fetch an HTTPS page. The canonical source for this example lives at https://github.com/ARMmbed/mbed-os-example-tls

HTTPS File Download Example for TLS Client on mbed OS

This application downloads a file from an HTTPS server (developer.mbed.org) and looks for a specific string in that file.

Getting started

Building with mbed CLI

If you'd like to use mbed CLI to build this, then you should set up your environment if you have not done so already. For instructions, refer to the main readme. The instructions here relate to using the developer.mbed.org Online Compiler

Import the program in to the Online Compiler, select your board from the drop down in the top right hand corner and then compile the application. Once it has built, you can drag and drop the binary onto your device.

Required hardware

This example also requires an Ethernet cable an connection to the internet additional to the hardware requirements in the main readme.

Monitoring the application

NOTE: Make sure that the Ethernet cable is plugged in correctly before running the application.

The output in the terminal window should be similar to this:

terminal output

Using Ethernet LWIP
Client IP Address is 10.2.203.43
Connecting with developer.mbed.org
Starting the TLS handshake...
TLS connection to developer.mbed.org established
Server certificate:
    cert. version     : 3
    serial number     : 11:21:B8:47:9B:21:6C:B1:C6:AF:BC:5D:0C:19:52:DC:D7:C3
    issuer name       : C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2
    subject name      : C=GB, ST=Cambridgeshire, L=Cambridge, O=ARM Ltd, CN=*.mbed.com
    issued  on        : 2016-03-03 12:26:08
    expires on        : 2017-04-05 10:31:02
    signed using      : RSA with SHA-256
    RSA key size      : 2048 bits
    basic constraints : CA=false
    subject alt name  : *.mbed.com, mbed.org, *.mbed.org, mbed.com
    key usage         : Digital Signature, Key Encipherment
    ext key usage     : TLS Web Server Authentication, TLS Web Client Authentication
Certificate verification passed

HTTPS: Received 439 chars from server
HTTPS: Received 200 OK status ... [OK]
HTTPS: Received 'Hello world!' status ... [OK]
HTTPS: Received message:

HTTP/1.1 200 OK
Server: nginx/1.7.10
Date: Wed, 20 Jul 2016 10:00:35 GMT
Content-Type: text/plain
Content-Length: 14
Connection: keep-alive
Last-Modified: Fri, 27 Jul 2012 13:30:34 GMT
Accept-Ranges: bytes
Cache-Control: max-age=36000
Expires: Wed, 20 Jul 2016 20:00:35 GMT
X-Upstream-L3: 172.17.0.3:80
X-Upstream-L2: developer-sjc-indigo-1-nginx
Strict-Transport-Security: max-age=31536000; includeSubdomains

Hello world!

Debugging the TLS connection

To print out more debug information about the TLS connection, edit the file `main.cpp` and change the definition of `DEBUG_LEVEL` (near the top of the file) from 0 to a positive number:

  • Level 1 only prints non-zero return codes from SSL functions and information about the full certificate chain being verified.
  • Level 2 prints more information about internal state updates.
  • Level 3 is intermediate.
  • Level 4 (the maximum) includes full binary dumps of the packets.

The TLS connection can fail with an error similar to:

error message

    mbedtls_ssl_write() failed: -0x2700 (-9984): X509 - Certificate verification failed, e.g. CRL, CA or signature check failed
    Failed to fetch /media/uploads/mbed_official/hello.txt from developer.mbed.org:443

This probably means you need to update the contents of the SSL_CA_PEM constant (this can happen if you modify HTTPS_SERVER_NAME, or when developer.mbed.org switches to a new CA when updating its certificate).

Another possible reason for this error is a proxy providing a different certificate. Proxies can be used in some network configurations or for performing man-in-the-middle attacks. If you choose to ignore this error and proceed with the connection anyway, you can change the definition of UNSAFE near the top of the file from 0 to 1.

Warning: this removes all security against a possible active attacker, so use at your own risk or for debugging only!

Committer:
mbed_official
Date:
Thu Sep 27 11:15:08 2018 +0100
Revision:
81:1b9acc423bfc
Parent:
76:b8c07be20122
Child:
83:6dbd4cae4527
Don't use easy-connet, use NetworkInterface::get_default_instance() (#198)


.
Commit copied from https://github.com/ARMmbed/mbed-os-example-tls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 66:ce8709d9912c 1 /*
mbed_official 66:ce8709d9912c 2 * Hello world example of a TLS client: fetch an HTTPS page
mbed_official 66:ce8709d9912c 3 *
mbed_official 66:ce8709d9912c 4 * Copyright (C) 2006-2018, Arm Limited, All Rights Reserved
mbed_official 66:ce8709d9912c 5 * SPDX-License-Identifier: Apache-2.0
mbed_official 66:ce8709d9912c 6 *
mbed_official 66:ce8709d9912c 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
mbed_official 66:ce8709d9912c 8 * not use this file except in compliance with the License.
mbed_official 66:ce8709d9912c 9 * You may obtain a copy of the License at
mbed_official 66:ce8709d9912c 10 *
mbed_official 66:ce8709d9912c 11 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 66:ce8709d9912c 12 *
mbed_official 66:ce8709d9912c 13 * Unless required by applicable law or agreed to in writing, software
mbed_official 66:ce8709d9912c 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
mbed_official 66:ce8709d9912c 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 66:ce8709d9912c 16 * See the License for the specific language governing permissions and
mbed_official 66:ce8709d9912c 17 * limitations under the License.
mbed_official 66:ce8709d9912c 18 *
mbed_official 66:ce8709d9912c 19 * This file is part of Mbed TLS (https://tls.mbed.org)
mbed_official 66:ce8709d9912c 20 */
mbed_official 66:ce8709d9912c 21
mbed_official 66:ce8709d9912c 22 #include "HelloHttpsClient.h"
mbed_official 66:ce8709d9912c 23
mbed_official 66:ce8709d9912c 24 #include "mbedtls/platform.h"
mbed_official 66:ce8709d9912c 25 #include "mbedtls/config.h"
mbed_official 66:ce8709d9912c 26 #include "mbedtls/ssl.h"
mbed_official 66:ce8709d9912c 27 #include "mbedtls/entropy.h"
mbed_official 66:ce8709d9912c 28 #include "mbedtls/ctr_drbg.h"
mbed_official 66:ce8709d9912c 29 #include "mbedtls/error.h"
mbed_official 66:ce8709d9912c 30 #include "mbedtls/debug.h"
mbed_official 66:ce8709d9912c 31
mbed_official 66:ce8709d9912c 32 #include <stdint.h>
mbed_official 66:ce8709d9912c 33 #include <string.h>
mbed_official 81:1b9acc423bfc 34 #include "mbed.h"
mbed_official 66:ce8709d9912c 35
mbed_official 66:ce8709d9912c 36 const char *HelloHttpsClient::DRBG_PERSONALIZED_STR =
mbed_official 66:ce8709d9912c 37 "Mbed TLS helloword client";
mbed_official 66:ce8709d9912c 38
mbed_official 66:ce8709d9912c 39 const size_t HelloHttpsClient::ERROR_LOG_BUFFER_LENGTH = 128;
mbed_official 66:ce8709d9912c 40
mbed_official 66:ce8709d9912c 41 const char *HelloHttpsClient::TLS_PEM_CA =
mbed_official 66:ce8709d9912c 42 "-----BEGIN CERTIFICATE-----\n"
mbed_official 66:ce8709d9912c 43 "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\n"
mbed_official 66:ce8709d9912c 44 "A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n"
mbed_official 66:ce8709d9912c 45 "b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\n"
mbed_official 66:ce8709d9912c 46 "MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\n"
mbed_official 66:ce8709d9912c 47 "YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\n"
mbed_official 66:ce8709d9912c 48 "aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\n"
mbed_official 66:ce8709d9912c 49 "jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\n"
mbed_official 66:ce8709d9912c 50 "xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n"
mbed_official 66:ce8709d9912c 51 "1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\n"
mbed_official 66:ce8709d9912c 52 "snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\n"
mbed_official 66:ce8709d9912c 53 "U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n"
mbed_official 66:ce8709d9912c 54 "9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\n"
mbed_official 66:ce8709d9912c 55 "BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\n"
mbed_official 66:ce8709d9912c 56 "AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\n"
mbed_official 66:ce8709d9912c 57 "yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n"
mbed_official 66:ce8709d9912c 58 "38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\n"
mbed_official 66:ce8709d9912c 59 "AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\n"
mbed_official 66:ce8709d9912c 60 "DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\n"
mbed_official 66:ce8709d9912c 61 "HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n"
mbed_official 66:ce8709d9912c 62 "-----END CERTIFICATE-----\n";
mbed_official 66:ce8709d9912c 63
mbed_official 66:ce8709d9912c 64 const char *HelloHttpsClient::HTTP_REQUEST_FILE_PATH =
mbed_official 66:ce8709d9912c 65 "/media/uploads/mbed_official/hello.txt";
mbed_official 66:ce8709d9912c 66
mbed_official 66:ce8709d9912c 67 const char *HelloHttpsClient::HTTP_HELLO_STR = "Hello world!";
mbed_official 66:ce8709d9912c 68
mbed_official 66:ce8709d9912c 69 const char *HelloHttpsClient::HTTP_OK_STR = "200 OK";
mbed_official 66:ce8709d9912c 70
mbed_official 66:ce8709d9912c 71 HelloHttpsClient::HelloHttpsClient(const char *in_server_name,
mbed_official 76:b8c07be20122 72 const char *in_server_addr,
mbed_official 69:ffefb2e2d149 73 const uint16_t in_server_port,
mbed_official 69:ffefb2e2d149 74 mbedtls_platform_context* in_platform_ctx) :
mbed_official 66:ce8709d9912c 75 socket(),
mbed_official 66:ce8709d9912c 76 server_name(in_server_name),
mbed_official 76:b8c07be20122 77 server_addr(in_server_addr),
mbed_official 69:ffefb2e2d149 78 server_port(in_server_port),
mbed_official 69:ffefb2e2d149 79 /* The platform context is passed just in case any crypto calls need it.
mbed_official 69:ffefb2e2d149 80 * Please refer to https://github.com/ARMmbed/mbedtls/issues/1200 for more
mbed_official 69:ffefb2e2d149 81 * information. */
mbed_official 69:ffefb2e2d149 82 platform_ctx(in_platform_ctx)
mbed_official 66:ce8709d9912c 83 {
mbed_official 66:ce8709d9912c 84 mbedtls_entropy_init(&entropy);
mbed_official 66:ce8709d9912c 85 mbedtls_ctr_drbg_init(&ctr_drbg);
mbed_official 66:ce8709d9912c 86 mbedtls_x509_crt_init(&cacert);
mbed_official 66:ce8709d9912c 87 mbedtls_ssl_init(&ssl);
mbed_official 66:ce8709d9912c 88 mbedtls_ssl_config_init(&ssl_conf);
mbed_official 66:ce8709d9912c 89 }
mbed_official 66:ce8709d9912c 90
mbed_official 66:ce8709d9912c 91 HelloHttpsClient::~HelloHttpsClient()
mbed_official 66:ce8709d9912c 92 {
mbed_official 66:ce8709d9912c 93 mbedtls_entropy_free(&entropy);
mbed_official 66:ce8709d9912c 94 mbedtls_ctr_drbg_free(&ctr_drbg);
mbed_official 66:ce8709d9912c 95 mbedtls_x509_crt_free(&cacert);
mbed_official 66:ce8709d9912c 96 mbedtls_ssl_free(&ssl);
mbed_official 66:ce8709d9912c 97 mbedtls_ssl_config_free(&ssl_conf);
mbed_official 66:ce8709d9912c 98
mbed_official 66:ce8709d9912c 99 socket.close();
mbed_official 66:ce8709d9912c 100 }
mbed_official 66:ce8709d9912c 101
mbed_official 66:ce8709d9912c 102 int HelloHttpsClient::run()
mbed_official 66:ce8709d9912c 103 {
mbed_official 66:ce8709d9912c 104 int ret;
mbed_official 66:ce8709d9912c 105 size_t req_len, req_offset, resp_offset;
mbed_official 66:ce8709d9912c 106 uint32_t flags;
mbed_official 66:ce8709d9912c 107 bool resp_200, resp_hello;
mbed_official 66:ce8709d9912c 108
mbed_official 66:ce8709d9912c 109 /* Configure the TCPSocket */
mbed_official 66:ce8709d9912c 110 if ((ret = configureTCPSocket()) != 0)
mbed_official 66:ce8709d9912c 111 return ret;
mbed_official 66:ce8709d9912c 112
mbed_official 66:ce8709d9912c 113 /* Configure already initialized Mbed TLS structures */
mbed_official 66:ce8709d9912c 114 if ((ret = configureTlsContexts()) != 0)
mbed_official 66:ce8709d9912c 115 return ret;
mbed_official 66:ce8709d9912c 116
mbed_official 66:ce8709d9912c 117 /* Start a connection to the server */
mbed_official 76:b8c07be20122 118 if ((ret = socket.connect(server_addr, server_port)) != NSAPI_ERROR_OK) {
mbed_official 66:ce8709d9912c 119 mbedtls_printf("socket.connect() returned %d\n", ret);
mbed_official 66:ce8709d9912c 120 return ret;
mbed_official 66:ce8709d9912c 121 }
mbed_official 66:ce8709d9912c 122 mbedtls_printf("Successfully connected to %s at port %u\n",
mbed_official 76:b8c07be20122 123 server_addr, server_port);
mbed_official 66:ce8709d9912c 124
mbed_official 66:ce8709d9912c 125 /* Start the TLS handshake */
mbed_official 66:ce8709d9912c 126 mbedtls_printf("Starting the TLS handshake...\n");
mbed_official 66:ce8709d9912c 127 do {
mbed_official 66:ce8709d9912c 128 ret = mbedtls_ssl_handshake(&ssl);
mbed_official 66:ce8709d9912c 129 } while(ret != 0 &&
mbed_official 66:ce8709d9912c 130 (ret == MBEDTLS_ERR_SSL_WANT_READ ||
mbed_official 66:ce8709d9912c 131 ret == MBEDTLS_ERR_SSL_WANT_WRITE));
mbed_official 66:ce8709d9912c 132 if (ret < 0) {
mbed_official 66:ce8709d9912c 133 mbedtls_printf("mbedtls_ssl_handshake() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 134 return ret;
mbed_official 66:ce8709d9912c 135 }
mbed_official 66:ce8709d9912c 136 mbedtls_printf("Successfully completed the TLS handshake\n");
mbed_official 66:ce8709d9912c 137
mbed_official 66:ce8709d9912c 138 /* Fill the request buffer */
mbed_official 66:ce8709d9912c 139 ret = snprintf(gp_buf, sizeof(gp_buf),
mbed_official 66:ce8709d9912c 140 "GET %s HTTP/1.1\nHost: %s\n\n", HTTP_REQUEST_FILE_PATH,
mbed_official 66:ce8709d9912c 141 server_name);
mbed_official 66:ce8709d9912c 142 req_len = static_cast<size_t>(ret);
mbed_official 66:ce8709d9912c 143 if (ret < 0 || req_len >= sizeof(gp_buf)) {
mbed_official 66:ce8709d9912c 144 mbedtls_printf("Failed to compose HTTP request using snprintf: %d\n",
mbed_official 66:ce8709d9912c 145 ret);
mbed_official 66:ce8709d9912c 146 return ret;
mbed_official 66:ce8709d9912c 147 }
mbed_official 66:ce8709d9912c 148
mbed_official 66:ce8709d9912c 149 /* Send the HTTP request to the server over TLS */
mbed_official 66:ce8709d9912c 150 req_offset = 0;
mbed_official 66:ce8709d9912c 151 do {
mbed_official 66:ce8709d9912c 152 ret = mbedtls_ssl_write(&ssl,
mbed_official 66:ce8709d9912c 153 reinterpret_cast<const unsigned char *>(gp_buf + req_offset),
mbed_official 66:ce8709d9912c 154 req_len - req_offset);
mbed_official 66:ce8709d9912c 155 if (ret > 0)
mbed_official 66:ce8709d9912c 156 req_offset += static_cast<size_t>(ret);
mbed_official 66:ce8709d9912c 157 }
mbed_official 66:ce8709d9912c 158 while(req_offset < req_len &&
mbed_official 66:ce8709d9912c 159 (ret > 0 ||
mbed_official 66:ce8709d9912c 160 ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
mbed_official 66:ce8709d9912c 161 ret == MBEDTLS_ERR_SSL_WANT_READ));
mbed_official 66:ce8709d9912c 162 if (ret < 0) {
mbed_official 66:ce8709d9912c 163 mbedtls_printf("mbedtls_ssl_write() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 164 return ret;
mbed_official 66:ce8709d9912c 165 }
mbed_official 66:ce8709d9912c 166
mbed_official 66:ce8709d9912c 167 /* Print information about the TLS connection */
mbed_official 66:ce8709d9912c 168 ret = mbedtls_x509_crt_info(gp_buf, sizeof(gp_buf),
mbed_official 66:ce8709d9912c 169 "\r ", mbedtls_ssl_get_peer_cert(&ssl));
mbed_official 66:ce8709d9912c 170 if (ret < 0) {
mbed_official 66:ce8709d9912c 171 mbedtls_printf("mbedtls_x509_crt_info() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 172 return ret;
mbed_official 66:ce8709d9912c 173 }
mbed_official 66:ce8709d9912c 174 mbedtls_printf("Server certificate:\n%s\n", gp_buf);
mbed_official 66:ce8709d9912c 175
mbed_official 66:ce8709d9912c 176 /* Ensure certificate verification was successful */
mbed_official 66:ce8709d9912c 177 flags = mbedtls_ssl_get_verify_result(&ssl);
mbed_official 66:ce8709d9912c 178 if (flags != 0) {
mbed_official 66:ce8709d9912c 179 ret = mbedtls_x509_crt_verify_info(gp_buf, sizeof(gp_buf),
mbed_official 66:ce8709d9912c 180 "\r ! ", flags);
mbed_official 66:ce8709d9912c 181 if (ret < 0) {
mbed_official 66:ce8709d9912c 182 mbedtls_printf("mbedtls_x509_crt_verify_info() returned "
mbed_official 66:ce8709d9912c 183 "-0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 184 return ret;
mbed_official 66:ce8709d9912c 185 } else {
mbed_official 66:ce8709d9912c 186 mbedtls_printf("Certificate verification failed (flags %lu):"
mbed_official 66:ce8709d9912c 187 "\n%s\n", flags, gp_buf);
mbed_official 66:ce8709d9912c 188 return -1;
mbed_official 66:ce8709d9912c 189 }
mbed_official 66:ce8709d9912c 190 } else {
mbed_official 66:ce8709d9912c 191 mbedtls_printf("Certificate verification passed\n");
mbed_official 66:ce8709d9912c 192 }
mbed_official 66:ce8709d9912c 193
mbed_official 66:ce8709d9912c 194 mbedtls_printf("Established TLS connection to %s\n", server_name);
mbed_official 66:ce8709d9912c 195
mbed_official 66:ce8709d9912c 196 /* Read response from the server */
mbed_official 66:ce8709d9912c 197 resp_offset = 0;
mbed_official 66:ce8709d9912c 198 resp_200 = false;
mbed_official 66:ce8709d9912c 199 resp_hello = false;
mbed_official 66:ce8709d9912c 200 do {
mbed_official 66:ce8709d9912c 201 ret = mbedtls_ssl_read(&ssl,
mbed_official 66:ce8709d9912c 202 reinterpret_cast<unsigned char *>(gp_buf + resp_offset),
mbed_official 66:ce8709d9912c 203 sizeof(gp_buf) - resp_offset - 1);
mbed_official 66:ce8709d9912c 204 if (ret > 0)
mbed_official 66:ce8709d9912c 205 resp_offset += static_cast<size_t>(ret);
mbed_official 66:ce8709d9912c 206
mbed_official 66:ce8709d9912c 207 /* Ensure that the response string is null-terminated */
mbed_official 66:ce8709d9912c 208 gp_buf[resp_offset] = '\0';
mbed_official 66:ce8709d9912c 209
mbed_official 66:ce8709d9912c 210 /* Check if we received expected string */
mbed_official 66:ce8709d9912c 211 resp_200 = resp_200 || strstr(gp_buf, HTTP_OK_STR) != NULL;
mbed_official 66:ce8709d9912c 212 resp_hello = resp_hello || strstr(gp_buf, HTTP_HELLO_STR) != NULL;
mbed_official 66:ce8709d9912c 213 } while((!resp_200 || !resp_hello) &&
mbed_official 66:ce8709d9912c 214 (ret > 0 ||
mbed_official 66:ce8709d9912c 215 ret == MBEDTLS_ERR_SSL_WANT_READ || MBEDTLS_ERR_SSL_WANT_WRITE));
mbed_official 66:ce8709d9912c 216 if (ret < 0) {
mbed_official 66:ce8709d9912c 217 mbedtls_printf("mbedtls_ssl_read() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 218 return ret;
mbed_official 66:ce8709d9912c 219 }
mbed_official 66:ce8709d9912c 220
mbed_official 66:ce8709d9912c 221 /* Display response information */
mbed_official 66:ce8709d9912c 222 mbedtls_printf("HTTP: Received %u chars from server\n", resp_offset);
mbed_official 66:ce8709d9912c 223 mbedtls_printf("HTTP: Received '%s' status ... %s\n", HTTP_OK_STR,
mbed_official 66:ce8709d9912c 224 resp_200 ? "OK" : "FAIL");
mbed_official 66:ce8709d9912c 225 mbedtls_printf("HTTP: Received message:\n%s\n", gp_buf);
mbed_official 66:ce8709d9912c 226
mbed_official 66:ce8709d9912c 227 return 0;
mbed_official 66:ce8709d9912c 228 }
mbed_official 66:ce8709d9912c 229
mbed_official 66:ce8709d9912c 230 int HelloHttpsClient::configureTCPSocket()
mbed_official 66:ce8709d9912c 231 {
mbed_official 66:ce8709d9912c 232 int ret;
mbed_official 66:ce8709d9912c 233
mbed_official 81:1b9acc423bfc 234 NetworkInterface *network = NetworkInterface::get_default_instance();
mbed_official 66:ce8709d9912c 235 if(network == NULL) {
mbed_official 81:1b9acc423bfc 236 mbedtls_printf("ERROR: No network interface found!\n");
mbed_official 66:ce8709d9912c 237 return -1;
mbed_official 66:ce8709d9912c 238 }
mbed_official 81:1b9acc423bfc 239 ret = network->connect();
mbed_official 81:1b9acc423bfc 240 if (ret != 0) {
mbed_official 81:1b9acc423bfc 241 mbedtls_printf("Error! network->connect() returned: %d\n", ret);
mbed_official 81:1b9acc423bfc 242 return ret;
mbed_official 81:1b9acc423bfc 243 }
mbed_official 66:ce8709d9912c 244
mbed_official 66:ce8709d9912c 245 if ((ret = socket.open(network)) != NSAPI_ERROR_OK) {
mbed_official 66:ce8709d9912c 246 mbedtls_printf("socket.open() returned %d\n", ret);
mbed_official 66:ce8709d9912c 247 return ret;
mbed_official 66:ce8709d9912c 248 }
mbed_official 66:ce8709d9912c 249
mbed_official 66:ce8709d9912c 250 socket.set_blocking(false);
mbed_official 66:ce8709d9912c 251
mbed_official 66:ce8709d9912c 252 return 0;
mbed_official 66:ce8709d9912c 253 }
mbed_official 66:ce8709d9912c 254
mbed_official 66:ce8709d9912c 255 int HelloHttpsClient::configureTlsContexts()
mbed_official 66:ce8709d9912c 256 {
mbed_official 66:ce8709d9912c 257 int ret;
mbed_official 66:ce8709d9912c 258
mbed_official 66:ce8709d9912c 259 ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
mbed_official 66:ce8709d9912c 260 reinterpret_cast<const unsigned char *>(DRBG_PERSONALIZED_STR),
mbed_official 66:ce8709d9912c 261 strlen(DRBG_PERSONALIZED_STR) + 1);
mbed_official 66:ce8709d9912c 262 if (ret != 0) {
mbed_official 66:ce8709d9912c 263 mbedtls_printf("mbedtls_ctr_drbg_seed() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 264 return ret;
mbed_official 66:ce8709d9912c 265 }
mbed_official 66:ce8709d9912c 266
mbed_official 66:ce8709d9912c 267 ret = mbedtls_x509_crt_parse(&cacert,
mbed_official 66:ce8709d9912c 268 reinterpret_cast<const unsigned char *>(TLS_PEM_CA),
mbed_official 66:ce8709d9912c 269 strlen(TLS_PEM_CA) + 1);
mbed_official 66:ce8709d9912c 270 if (ret != 0) {
mbed_official 66:ce8709d9912c 271 mbedtls_printf("mbedtls_x509_crt_parse() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 272 return ret;
mbed_official 66:ce8709d9912c 273 }
mbed_official 66:ce8709d9912c 274
mbed_official 66:ce8709d9912c 275 ret = mbedtls_ssl_config_defaults(&ssl_conf, MBEDTLS_SSL_IS_CLIENT,
mbed_official 66:ce8709d9912c 276 MBEDTLS_SSL_TRANSPORT_STREAM,
mbed_official 66:ce8709d9912c 277 MBEDTLS_SSL_PRESET_DEFAULT);
mbed_official 66:ce8709d9912c 278 if (ret != 0) {
mbed_official 66:ce8709d9912c 279 mbedtls_printf("mbedtls_ssl_config_defaults() returned -0x%04X\n",
mbed_official 66:ce8709d9912c 280 -ret);
mbed_official 66:ce8709d9912c 281 return ret;
mbed_official 66:ce8709d9912c 282 }
mbed_official 66:ce8709d9912c 283
mbed_official 66:ce8709d9912c 284 mbedtls_ssl_conf_ca_chain(&ssl_conf, &cacert, NULL);
mbed_official 66:ce8709d9912c 285 mbedtls_ssl_conf_rng(&ssl_conf, mbedtls_ctr_drbg_random, &ctr_drbg);
mbed_official 66:ce8709d9912c 286
mbed_official 66:ce8709d9912c 287 /*
mbed_official 66:ce8709d9912c 288 * It is possible to disable authentication by passing
mbed_official 66:ce8709d9912c 289 * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
mbed_official 66:ce8709d9912c 290 */
mbed_official 66:ce8709d9912c 291 mbedtls_ssl_conf_authmode(&ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbed_official 66:ce8709d9912c 292
mbed_official 66:ce8709d9912c 293 #if HELLO_HTTPS_CLIENT_DEBUG_LEVEL > 0
mbed_official 66:ce8709d9912c 294 mbedtls_ssl_conf_verify(&ssl_conf, sslVerify, this);
mbed_official 66:ce8709d9912c 295 mbedtls_ssl_conf_dbg(&ssl_conf, sslDebug, NULL);
mbed_official 66:ce8709d9912c 296 mbedtls_debug_set_threshold(HELLO_HTTPS_CLIENT_DEBUG_LEVEL);
mbed_official 66:ce8709d9912c 297 #endif /* HELLO_HTTPS_CLIENT_DEBUG_LEVEL > 0 */
mbed_official 66:ce8709d9912c 298
mbed_official 66:ce8709d9912c 299 if ((ret = mbedtls_ssl_setup( &ssl, &ssl_conf)) != 0) {
mbed_official 66:ce8709d9912c 300 mbedtls_printf("mbedtls_ssl_setup() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 301 return ret;
mbed_official 66:ce8709d9912c 302 }
mbed_official 66:ce8709d9912c 303
mbed_official 66:ce8709d9912c 304 if ((ret = mbedtls_ssl_set_hostname( &ssl, server_name )) != 0) {
mbed_official 66:ce8709d9912c 305 mbedtls_printf("mbedtls_ssl_set_hostname() returned -0x%04X\n",
mbed_official 66:ce8709d9912c 306 -ret);
mbed_official 66:ce8709d9912c 307 return ret;
mbed_official 66:ce8709d9912c 308 }
mbed_official 66:ce8709d9912c 309
mbed_official 66:ce8709d9912c 310 mbedtls_ssl_set_bio(&ssl, static_cast<void *>(&socket), sslSend, sslRecv,
mbed_official 66:ce8709d9912c 311 NULL);
mbed_official 66:ce8709d9912c 312
mbed_official 66:ce8709d9912c 313 return 0;
mbed_official 66:ce8709d9912c 314 }
mbed_official 66:ce8709d9912c 315
mbed_official 66:ce8709d9912c 316 int HelloHttpsClient::sslRecv(void *ctx, unsigned char *buf, size_t len)
mbed_official 66:ce8709d9912c 317 {
mbed_official 66:ce8709d9912c 318 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
mbed_official 66:ce8709d9912c 319 int ret = socket->recv(buf, len);
mbed_official 66:ce8709d9912c 320
mbed_official 66:ce8709d9912c 321 if (ret == NSAPI_ERROR_WOULD_BLOCK)
mbed_official 66:ce8709d9912c 322 ret = MBEDTLS_ERR_SSL_WANT_READ;
mbed_official 66:ce8709d9912c 323 else if (ret < 0)
mbed_official 66:ce8709d9912c 324 mbedtls_printf("socket.recv() returned %d\n", ret);
mbed_official 66:ce8709d9912c 325
mbed_official 66:ce8709d9912c 326 return ret;
mbed_official 66:ce8709d9912c 327 }
mbed_official 66:ce8709d9912c 328
mbed_official 66:ce8709d9912c 329 int HelloHttpsClient::sslSend(void *ctx, const unsigned char *buf, size_t len)
mbed_official 66:ce8709d9912c 330 {
mbed_official 66:ce8709d9912c 331 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
mbed_official 66:ce8709d9912c 332 int ret = socket->send(buf, len);
mbed_official 66:ce8709d9912c 333
mbed_official 66:ce8709d9912c 334 if (ret == NSAPI_ERROR_WOULD_BLOCK)
mbed_official 66:ce8709d9912c 335 ret = MBEDTLS_ERR_SSL_WANT_WRITE;
mbed_official 66:ce8709d9912c 336 else if (ret < 0)
mbed_official 66:ce8709d9912c 337 mbedtls_printf("socket.send() returned %d\n", ret);
mbed_official 66:ce8709d9912c 338
mbed_official 66:ce8709d9912c 339 return ret;
mbed_official 66:ce8709d9912c 340 }
mbed_official 66:ce8709d9912c 341
mbed_official 66:ce8709d9912c 342 void HelloHttpsClient::sslDebug(void *ctx, int level, const char *file,
mbed_official 66:ce8709d9912c 343 int line, const char *str)
mbed_official 66:ce8709d9912c 344 {
mbed_official 66:ce8709d9912c 345 (void)ctx;
mbed_official 66:ce8709d9912c 346
mbed_official 66:ce8709d9912c 347 const char *p, *basename;
mbed_official 66:ce8709d9912c 348
mbed_official 66:ce8709d9912c 349 /* Extract basename from file */
mbed_official 66:ce8709d9912c 350 for (p = basename = file; *p != '\0'; p++) {
mbed_official 66:ce8709d9912c 351 if (*p == '/' || *p == '\\')
mbed_official 66:ce8709d9912c 352 basename = p + 1;
mbed_official 66:ce8709d9912c 353 }
mbed_official 66:ce8709d9912c 354
mbed_official 66:ce8709d9912c 355 mbedtls_printf("%s:%d: |%d| %s\r", basename, line, level, str);
mbed_official 66:ce8709d9912c 356 }
mbed_official 66:ce8709d9912c 357
mbed_official 66:ce8709d9912c 358 int HelloHttpsClient::sslVerify(void *ctx, mbedtls_x509_crt *crt, int depth,
mbed_official 66:ce8709d9912c 359 uint32_t *flags)
mbed_official 66:ce8709d9912c 360 {
mbed_official 66:ce8709d9912c 361 HelloHttpsClient *client = static_cast<HelloHttpsClient *>(ctx);
mbed_official 66:ce8709d9912c 362
mbed_official 66:ce8709d9912c 363 int ret = -1;
mbed_official 66:ce8709d9912c 364
mbed_official 66:ce8709d9912c 365 ret = mbedtls_x509_crt_info(client->gp_buf, sizeof(gp_buf), "\r ", crt);
mbed_official 66:ce8709d9912c 366 if (ret < 0) {
mbed_official 66:ce8709d9912c 367 mbedtls_printf("mbedtls_x509_crt_info() returned -0x%04X\n", -ret);
mbed_official 66:ce8709d9912c 368 } else {
mbed_official 66:ce8709d9912c 369 ret = 0;
mbed_official 66:ce8709d9912c 370 mbedtls_printf("Verifying certificate at depth %d:\n%s\n",
mbed_official 66:ce8709d9912c 371 depth, client->gp_buf);
mbed_official 66:ce8709d9912c 372 }
mbed_official 66:ce8709d9912c 373
mbed_official 66:ce8709d9912c 374 return ret;
mbed_official 66:ce8709d9912c 375 }
mbed_official 66:ce8709d9912c 376