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:
Mon Nov 18 14:00:49 2019 +0000
Revision:
98:54b91f4b0c49
Parent:
95:d282bc7f32e4
Merge pull request #264 from dgreen-arm/point-master-at-mbed-os-master

Point master branch at Mbed OS master
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-tls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Janos Follath 0:fc70c47eecb4 1 /*
Janos Follath 0:fc70c47eecb4 2 * Hello world example of a TLS client: fetch an HTTPS page
Janos Follath 0:fc70c47eecb4 3 *
mbed_official 66:ce8709d9912c 4 * Copyright (C) 2006-2018, Arm Limited, All Rights Reserved
Janos Follath 0:fc70c47eecb4 5 * SPDX-License-Identifier: Apache-2.0
Janos Follath 0:fc70c47eecb4 6 *
Janos Follath 0:fc70c47eecb4 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Janos Follath 0:fc70c47eecb4 8 * not use this file except in compliance with the License.
Janos Follath 0:fc70c47eecb4 9 * You may obtain a copy of the License at
Janos Follath 0:fc70c47eecb4 10 *
Janos Follath 0:fc70c47eecb4 11 * http://www.apache.org/licenses/LICENSE-2.0
Janos Follath 0:fc70c47eecb4 12 *
Janos Follath 0:fc70c47eecb4 13 * Unless required by applicable law or agreed to in writing, software
Janos Follath 0:fc70c47eecb4 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Janos Follath 0:fc70c47eecb4 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Janos Follath 0:fc70c47eecb4 16 * See the License for the specific language governing permissions and
Janos Follath 0:fc70c47eecb4 17 * limitations under the License.
Janos Follath 0:fc70c47eecb4 18 *
mbed_official 50:b6870173bcac 19 * This file is part of Mbed TLS (https://tls.mbed.org)
mbed_official 12:1ae41c231014 20 */
Janos Follath 0:fc70c47eecb4 21
mbed_official 66:ce8709d9912c 22 /**
mbed_official 66:ce8709d9912c 23 * \file main.cpp
mbed_official 66:ce8709d9912c 24 *
mbed_official 66:ce8709d9912c 25 * \brief An example TLS Client application
Janos Follath 0:fc70c47eecb4 26 *
mbed_official 66:ce8709d9912c 27 * This application sends an HTTPS request to os.mbed.com and searches
mbed_official 66:ce8709d9912c 28 * for a string in the result.
mbed_official 66:ce8709d9912c 29 *
mbed_official 66:ce8709d9912c 30 * This example is implemented as a logic class (HelloHttpsClient) wrapping a
mbed_official 66:ce8709d9912c 31 * TCP socket. The logic class handles all events, leaving the main loop to just
mbed_official 66:ce8709d9912c 32 * check if the process has finished.
Janos Follath 0:fc70c47eecb4 33 */
Janos Follath 0:fc70c47eecb4 34
Janos Follath 0:fc70c47eecb4 35 #include "mbed.h"
Janos Follath 0:fc70c47eecb4 36
Janos Follath 0:fc70c47eecb4 37 #include "mbedtls/platform.h"
mbed_official 95:d282bc7f32e4 38 #if defined(MBEDTLS_USE_PSA_CRYPTO)
mbed_official 95:d282bc7f32e4 39 #include "psa/crypto.h"
mbed_official 95:d282bc7f32e4 40 #endif /* MBEDTLS_USE_PSA_CRYPTO */
mbed_official 12:1ae41c231014 41
mbed_official 66:ce8709d9912c 42 #include "HelloHttpsClient.h"
Janos Follath 0:fc70c47eecb4 43
mbed_official 66:ce8709d9912c 44 /* Domain/IP address of the server to contact */
mbed_official 66:ce8709d9912c 45 const char SERVER_NAME[] = "os.mbed.com";
mbed_official 76:b8c07be20122 46 const char SERVER_ADDR[] = "os.mbed.com";
Janos Follath 0:fc70c47eecb4 47
mbed_official 66:ce8709d9912c 48 /* Port used to connect to the server */
mbed_official 66:ce8709d9912c 49 const int SERVER_PORT = 443;
Janos Follath 0:fc70c47eecb4 50
Janos Follath 0:fc70c47eecb4 51 /**
mbed_official 66:ce8709d9912c 52 * The main function driving the HTTPS client.
Janos Follath 0:fc70c47eecb4 53 */
mbed_official 66:ce8709d9912c 54 int main()
mbed_official 66:ce8709d9912c 55 {
mbed_official 69:ffefb2e2d149 56 int exit_code = MBEDTLS_EXIT_FAILURE;
mbed_official 69:ffefb2e2d149 57
mbed_official 86:e1ceb1075f1a 58 if((exit_code = mbedtls_platform_setup(NULL)) != 0) {
mbed_official 69:ffefb2e2d149 59 printf("Platform initialization failed with error %d\r\n", exit_code);
mbed_official 69:ffefb2e2d149 60 return MBEDTLS_EXIT_FAILURE;
mbed_official 69:ffefb2e2d149 61 }
mbed_official 95:d282bc7f32e4 62
mbed_official 95:d282bc7f32e4 63 #if defined(MBEDTLS_USE_PSA_CRYPTO)
mbed_official 95:d282bc7f32e4 64 /*
mbed_official 95:d282bc7f32e4 65 * Initialize underlying PSA Crypto implementation.
mbed_official 95:d282bc7f32e4 66 * Even if the HTTPS client doesn't make use of
mbed_official 95:d282bc7f32e4 67 * PSA-specific API, for example for setting opaque PSKs
mbed_official 95:d282bc7f32e4 68 * or opaque private keys, Mbed TLS will use PSA
mbed_official 95:d282bc7f32e4 69 * for public and symmetric key operations as well as
mbed_official 95:d282bc7f32e4 70 * hashing.
mbed_official 95:d282bc7f32e4 71 */
mbed_official 95:d282bc7f32e4 72 psa_status_t status;
mbed_official 95:d282bc7f32e4 73 status = psa_crypto_init();
mbed_official 95:d282bc7f32e4 74 if( status != PSA_SUCCESS )
mbed_official 95:d282bc7f32e4 75 {
mbed_official 95:d282bc7f32e4 76 printf("psa_crypto_init() failed with %d\r\n", status );
mbed_official 95:d282bc7f32e4 77 return MBEDTLS_EXIT_FAILURE;
mbed_official 95:d282bc7f32e4 78 }
mbed_official 95:d282bc7f32e4 79 #endif /* MBEDTLS_USE_PSA_CRYPTO */
mbed_official 95:d282bc7f32e4 80
mbed_official 66:ce8709d9912c 81 /*
mbed_official 66:ce8709d9912c 82 * The default 9600 bps is too slow to print full TLS debug info and could
mbed_official 66:ce8709d9912c 83 * cause the other party to time out.
Janos Follath 0:fc70c47eecb4 84 */
Janos Follath 0:fc70c47eecb4 85
mbed_official 66:ce8709d9912c 86 HelloHttpsClient *client;
Janos Follath 0:fc70c47eecb4 87
mbed_official 66:ce8709d9912c 88 mbedtls_printf("Starting mbed-os-example-tls/tls-client\n");
Janos Follath 0:fc70c47eecb4 89
mbed_official 66:ce8709d9912c 90 #if defined(MBED_MAJOR_VERSION)
mbed_official 66:ce8709d9912c 91 mbedtls_printf("Using Mbed OS %d.%d.%d\n",
mbed_official 66:ce8709d9912c 92 MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
mbed_official 66:ce8709d9912c 93 #else
mbed_official 66:ce8709d9912c 94 printf("Using Mbed OS from master.\n");
mbed_official 66:ce8709d9912c 95 #endif /* MBEDTLS_MAJOR_VERSION */
Janos Follath 0:fc70c47eecb4 96
mbed_official 66:ce8709d9912c 97 /* Allocate a HTTPS client */
mbed_official 86:e1ceb1075f1a 98 client = new (std::nothrow) HelloHttpsClient(SERVER_NAME, SERVER_ADDR, SERVER_PORT);
mbed_official 76:b8c07be20122 99
mbed_official 66:ce8709d9912c 100 if (client == NULL) {
mbed_official 66:ce8709d9912c 101 mbedtls_printf("Failed to allocate HelloHttpsClient object\n"
mbed_official 66:ce8709d9912c 102 "\nFAIL\n");
mbed_official 86:e1ceb1075f1a 103 mbedtls_platform_teardown(NULL);
mbed_official 66:ce8709d9912c 104 return exit_code;
Janos Follath 0:fc70c47eecb4 105 }
mbed_official 33:34783d5deafd 106
mbed_official 66:ce8709d9912c 107 /* Run the client */
mbed_official 66:ce8709d9912c 108 if (client->run() != 0) {
mbed_official 66:ce8709d9912c 109 mbedtls_printf("\nFAIL\n");
mbed_official 66:ce8709d9912c 110 } else {
mbed_official 66:ce8709d9912c 111 exit_code = MBEDTLS_EXIT_SUCCESS;
mbed_official 66:ce8709d9912c 112 mbedtls_printf("\nDONE\n");
Janos Follath 0:fc70c47eecb4 113 }
Janos Follath 0:fc70c47eecb4 114
mbed_official 66:ce8709d9912c 115 delete client;
Janos Follath 0:fc70c47eecb4 116
mbed_official 86:e1ceb1075f1a 117 mbedtls_platform_teardown(NULL);
mbed_official 66:ce8709d9912c 118 return exit_code;
Janos Follath 0:fc70c47eecb4 119 }