Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: WNCInterface mbed-rtos mbed
main.cpp@16:3bac55ad2049, 2016-11-02 (annotated)
- Committer:
- JMF
- Date:
- Wed Nov 02 19:20:20 2016 +0000
- Revision:
- 16:3bac55ad2049
- Parent:
- 13:1ae41c231014
An example program showing how to perform HTTPS interactions.
Who changed what in which revision?
| User | Revision | Line number | New 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 | * |
| Janos Follath |
0:fc70c47eecb4 | 4 | * Copyright (C) 2006-2016, 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 | * |
| Janos Follath |
0:fc70c47eecb4 | 19 | * This file is part of mbed TLS (https://tls.mbed.org) |
| mbed_official | 13:1ae41c231014 | 20 | */ |
| Janos Follath |
0:fc70c47eecb4 | 21 | |
| Janos Follath |
0:fc70c47eecb4 | 22 | /** \file main.cpp |
| Janos Follath |
0:fc70c47eecb4 | 23 | * \brief An example TLS Client application |
| Janos Follath |
0:fc70c47eecb4 | 24 | * This application sends an HTTPS request to developer.mbed.org and searches for a string in |
| Janos Follath |
0:fc70c47eecb4 | 25 | * the result. |
| Janos Follath |
0:fc70c47eecb4 | 26 | * |
| Janos Follath |
0:fc70c47eecb4 | 27 | * This example is implemented as a logic class (HelloHTTPS) wrapping a TCP socket. |
| Janos Follath |
0:fc70c47eecb4 | 28 | * The logic class handles all events, leaving the main loop to just check if the process |
| Janos Follath |
0:fc70c47eecb4 | 29 | * has finished. |
| Janos Follath |
0:fc70c47eecb4 | 30 | */ |
| Janos Follath |
0:fc70c47eecb4 | 31 | |
| Janos Follath |
0:fc70c47eecb4 | 32 | /* Change to a number between 1 and 4 to debug the TLS connection */ |
| Janos Follath |
0:fc70c47eecb4 | 33 | #define DEBUG_LEVEL 0 |
| Janos Follath |
0:fc70c47eecb4 | 34 | |
| Janos Follath |
0:fc70c47eecb4 | 35 | #include "mbed.h" |
| JMF | 16:3bac55ad2049 | 36 | //#include "NetworkStack.h" |
| Janos Follath |
0:fc70c47eecb4 | 37 | |
| JMF | 16:3bac55ad2049 | 38 | #include "WNCInterface.h" |
| JMF | 16:3bac55ad2049 | 39 | #include "TCPSocketConnection.h" |
| Janos Follath |
0:fc70c47eecb4 | 40 | |
| Janos Follath |
0:fc70c47eecb4 | 41 | #include "mbedtls/platform.h" |
| Janos Follath |
0:fc70c47eecb4 | 42 | #include "mbedtls/ssl.h" |
| Janos Follath |
0:fc70c47eecb4 | 43 | #include "mbedtls/entropy.h" |
| Janos Follath |
0:fc70c47eecb4 | 44 | #include "mbedtls/ctr_drbg.h" |
| Janos Follath |
0:fc70c47eecb4 | 45 | #include "mbedtls/error.h" |
| mbed_official | 13:1ae41c231014 | 46 | |
| JMF | 16:3bac55ad2049 | 47 | #define CRLF "\r\n" |
| JMF | 16:3bac55ad2049 | 48 | |
| Janos Follath |
0:fc70c47eecb4 | 49 | #if DEBUG_LEVEL > 0 |
| Janos Follath |
0:fc70c47eecb4 | 50 | #include "mbedtls/debug.h" |
| Janos Follath |
0:fc70c47eecb4 | 51 | #endif |
| Janos Follath |
0:fc70c47eecb4 | 52 | |
| Janos Follath |
0:fc70c47eecb4 | 53 | namespace { |
| Janos Follath |
0:fc70c47eecb4 | 54 | |
| Janos Follath |
0:fc70c47eecb4 | 55 | const char *HTTPS_SERVER_NAME = "developer.mbed.org"; |
| Janos Follath |
0:fc70c47eecb4 | 56 | const int HTTPS_SERVER_PORT = 443; |
| Janos Follath |
0:fc70c47eecb4 | 57 | const int RECV_BUFFER_SIZE = 600; |
| Janos Follath |
0:fc70c47eecb4 | 58 | |
| Janos Follath |
0:fc70c47eecb4 | 59 | const char HTTPS_PATH[] = "/media/uploads/mbed_official/hello.txt"; |
| JMF | 16:3bac55ad2049 | 60 | //const size_t HTTPS_PATH_LEN = sizeof(HTTPS_PATH) - 1; |
| Janos Follath |
0:fc70c47eecb4 | 61 | |
| Janos Follath |
0:fc70c47eecb4 | 62 | /* Test related data */ |
| Janos Follath |
0:fc70c47eecb4 | 63 | const char *HTTPS_OK_STR = "200 OK"; |
| Janos Follath |
0:fc70c47eecb4 | 64 | const char *HTTPS_HELLO_STR = "Hello world!"; |
| Janos Follath |
0:fc70c47eecb4 | 65 | |
| Janos Follath |
0:fc70c47eecb4 | 66 | /* personalization string for the drbg */ |
| Janos Follath |
0:fc70c47eecb4 | 67 | const char *DRBG_PERS = "mbed TLS helloword client"; |
| Janos Follath |
0:fc70c47eecb4 | 68 | |
| Janos Follath |
0:fc70c47eecb4 | 69 | /* List of trusted root CA certificates |
| Janos Follath |
0:fc70c47eecb4 | 70 | * currently only GlobalSign, the CA for developer.mbed.org |
| Janos Follath |
0:fc70c47eecb4 | 71 | * |
| Janos Follath |
0:fc70c47eecb4 | 72 | * To add more than one root, just concatenate them. |
| Janos Follath |
0:fc70c47eecb4 | 73 | */ |
| mbed_official | 13:1ae41c231014 | 74 | const char SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n" |
| mbed_official | 13:1ae41c231014 | 75 | "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\n" |
| mbed_official | 13:1ae41c231014 | 76 | "A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n" |
| mbed_official | 13:1ae41c231014 | 77 | "b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\n" |
| mbed_official | 13:1ae41c231014 | 78 | "MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\n" |
| mbed_official | 13:1ae41c231014 | 79 | "YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\n" |
| mbed_official | 13:1ae41c231014 | 80 | "aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\n" |
| mbed_official | 13:1ae41c231014 | 81 | "jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\n" |
| mbed_official | 13:1ae41c231014 | 82 | "xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n" |
| mbed_official | 13:1ae41c231014 | 83 | "1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\n" |
| mbed_official | 13:1ae41c231014 | 84 | "snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\n" |
| mbed_official | 13:1ae41c231014 | 85 | "U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n" |
| mbed_official | 13:1ae41c231014 | 86 | "9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\n" |
| mbed_official | 13:1ae41c231014 | 87 | "BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\n" |
| mbed_official | 13:1ae41c231014 | 88 | "AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\n" |
| mbed_official | 13:1ae41c231014 | 89 | "yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n" |
| mbed_official | 13:1ae41c231014 | 90 | "38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\n" |
| mbed_official | 13:1ae41c231014 | 91 | "AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\n" |
| mbed_official | 13:1ae41c231014 | 92 | "DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\n" |
| mbed_official | 13:1ae41c231014 | 93 | "HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n" |
| mbed_official | 13:1ae41c231014 | 94 | "-----END CERTIFICATE-----\n"; |
| Janos Follath |
0:fc70c47eecb4 | 95 | |
| Janos Follath |
0:fc70c47eecb4 | 96 | } |
| Janos Follath |
0:fc70c47eecb4 | 97 | |
| Janos Follath |
0:fc70c47eecb4 | 98 | /** |
| Janos Follath |
0:fc70c47eecb4 | 99 | * \brief HelloHTTPS implements the logic for fetching a file from a webserver |
| Janos Follath |
0:fc70c47eecb4 | 100 | * using a TCP socket and parsing the result. |
| Janos Follath |
0:fc70c47eecb4 | 101 | */ |
| Janos Follath |
0:fc70c47eecb4 | 102 | class HelloHTTPS { |
| Janos Follath |
0:fc70c47eecb4 | 103 | public: |
| Janos Follath |
0:fc70c47eecb4 | 104 | /** |
| Janos Follath |
0:fc70c47eecb4 | 105 | * HelloHTTPS Constructor |
| Janos Follath |
0:fc70c47eecb4 | 106 | * Initializes the TCP socket, sets up event handlers and flags. |
| Janos Follath |
0:fc70c47eecb4 | 107 | * |
| Janos Follath |
0:fc70c47eecb4 | 108 | * @param[in] domain The domain name to fetch from |
| Janos Follath |
0:fc70c47eecb4 | 109 | * @param[in] port The port of the HTTPS server |
| Janos Follath |
0:fc70c47eecb4 | 110 | */ |
| JMF | 16:3bac55ad2049 | 111 | HelloHTTPS(const char * domain, const uint16_t port, WNCInterface *net_iface) : |
| Janos Follath |
0:fc70c47eecb4 | 112 | _domain(domain), _port(port) |
| Janos Follath |
0:fc70c47eecb4 | 113 | { |
| Janos Follath |
0:fc70c47eecb4 | 114 | |
| Janos Follath |
0:fc70c47eecb4 | 115 | _error = false; |
| Janos Follath |
0:fc70c47eecb4 | 116 | _gothello = false; |
| Janos Follath |
0:fc70c47eecb4 | 117 | _got200 = false; |
| Janos Follath |
0:fc70c47eecb4 | 118 | _bpos = 0; |
| Janos Follath |
0:fc70c47eecb4 | 119 | _request_sent = 0; |
| JMF | 16:3bac55ad2049 | 120 | _tcpsocket = new TCPSocketConnection; |
| Janos Follath |
0:fc70c47eecb4 | 121 | |
| Janos Follath |
0:fc70c47eecb4 | 122 | mbedtls_entropy_init(&_entropy); |
| Janos Follath |
0:fc70c47eecb4 | 123 | mbedtls_ctr_drbg_init(&_ctr_drbg); |
| Janos Follath |
0:fc70c47eecb4 | 124 | mbedtls_x509_crt_init(&_cacert); |
| Janos Follath |
0:fc70c47eecb4 | 125 | mbedtls_ssl_init(&_ssl); |
| Janos Follath |
0:fc70c47eecb4 | 126 | mbedtls_ssl_config_init(&_ssl_conf); |
| Janos Follath |
0:fc70c47eecb4 | 127 | } |
| Janos Follath |
0:fc70c47eecb4 | 128 | /** |
| Janos Follath |
0:fc70c47eecb4 | 129 | * HelloHTTPS Desctructor |
| Janos Follath |
0:fc70c47eecb4 | 130 | */ |
| Janos Follath |
0:fc70c47eecb4 | 131 | ~HelloHTTPS() { |
| Janos Follath |
0:fc70c47eecb4 | 132 | mbedtls_entropy_free(&_entropy); |
| Janos Follath |
0:fc70c47eecb4 | 133 | mbedtls_ctr_drbg_free(&_ctr_drbg); |
| Janos Follath |
0:fc70c47eecb4 | 134 | mbedtls_x509_crt_free(&_cacert); |
| Janos Follath |
0:fc70c47eecb4 | 135 | mbedtls_ssl_free(&_ssl); |
| Janos Follath |
0:fc70c47eecb4 | 136 | mbedtls_ssl_config_free(&_ssl_conf); |
| Janos Follath |
0:fc70c47eecb4 | 137 | } |
| Janos Follath |
0:fc70c47eecb4 | 138 | /** |
| Janos Follath |
0:fc70c47eecb4 | 139 | * Start the test. |
| Janos Follath |
0:fc70c47eecb4 | 140 | * |
| Janos Follath |
0:fc70c47eecb4 | 141 | * Starts by clearing test flags, then resolves the address with DNS. |
| Janos Follath |
0:fc70c47eecb4 | 142 | * |
| Janos Follath |
0:fc70c47eecb4 | 143 | * @param[in] path The path of the file to fetch from the HTTPS server |
| Janos Follath |
0:fc70c47eecb4 | 144 | * @return SOCKET_ERROR_NONE on success, or an error code on failure |
| Janos Follath |
0:fc70c47eecb4 | 145 | */ |
| Janos Follath |
0:fc70c47eecb4 | 146 | void startTest(const char *path) { |
| Janos Follath |
0:fc70c47eecb4 | 147 | /* Initialize the flags */ |
| Janos Follath |
0:fc70c47eecb4 | 148 | _got200 = false; |
| Janos Follath |
0:fc70c47eecb4 | 149 | _gothello = false; |
| Janos Follath |
0:fc70c47eecb4 | 150 | _error = false; |
| Janos Follath |
0:fc70c47eecb4 | 151 | _disconnected = false; |
| Janos Follath |
0:fc70c47eecb4 | 152 | _request_sent = false; |
| Janos Follath |
0:fc70c47eecb4 | 153 | /* Fill the request buffer */ |
| Janos Follath |
0:fc70c47eecb4 | 154 | _bpos = snprintf(_buffer, sizeof(_buffer) - 1, "GET %s HTTP/1.1\nHost: %s\n\n", path, HTTPS_SERVER_NAME); |
| Janos Follath |
0:fc70c47eecb4 | 155 | |
| Janos Follath |
0:fc70c47eecb4 | 156 | /* |
| Janos Follath |
0:fc70c47eecb4 | 157 | * Initialize TLS-related stuf. |
| Janos Follath |
0:fc70c47eecb4 | 158 | */ |
| Janos Follath |
0:fc70c47eecb4 | 159 | int ret; |
| Janos Follath |
0:fc70c47eecb4 | 160 | if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy, |
| Janos Follath |
0:fc70c47eecb4 | 161 | (const unsigned char *) DRBG_PERS, |
| Janos Follath |
0:fc70c47eecb4 | 162 | sizeof (DRBG_PERS))) != 0) { |
| Janos Follath |
0:fc70c47eecb4 | 163 | print_mbedtls_error("mbedtls_crt_drbg_init", ret); |
| Janos Follath |
0:fc70c47eecb4 | 164 | _error = true; |
| Janos Follath |
0:fc70c47eecb4 | 165 | return; |
| Janos Follath |
0:fc70c47eecb4 | 166 | } |
| Janos Follath |
0:fc70c47eecb4 | 167 | |
| Janos Follath |
0:fc70c47eecb4 | 168 | if ((ret = mbedtls_x509_crt_parse(&_cacert, (const unsigned char *) SSL_CA_PEM, |
| Janos Follath |
0:fc70c47eecb4 | 169 | sizeof (SSL_CA_PEM))) != 0) { |
| Janos Follath |
0:fc70c47eecb4 | 170 | print_mbedtls_error("mbedtls_x509_crt_parse", ret); |
| Janos Follath |
0:fc70c47eecb4 | 171 | _error = true; |
| Janos Follath |
0:fc70c47eecb4 | 172 | return; |
| Janos Follath |
0:fc70c47eecb4 | 173 | } |
| Janos Follath |
0:fc70c47eecb4 | 174 | |
| Janos Follath |
0:fc70c47eecb4 | 175 | if ((ret = mbedtls_ssl_config_defaults(&_ssl_conf, |
| Janos Follath |
0:fc70c47eecb4 | 176 | MBEDTLS_SSL_IS_CLIENT, |
| Janos Follath |
0:fc70c47eecb4 | 177 | MBEDTLS_SSL_TRANSPORT_STREAM, |
| Janos Follath |
0:fc70c47eecb4 | 178 | MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { |
| Janos Follath |
0:fc70c47eecb4 | 179 | print_mbedtls_error("mbedtls_ssl_config_defaults", ret); |
| Janos Follath |
0:fc70c47eecb4 | 180 | _error = true; |
| Janos Follath |
0:fc70c47eecb4 | 181 | return; |
| Janos Follath |
0:fc70c47eecb4 | 182 | } |
| Janos Follath |
0:fc70c47eecb4 | 183 | |
| Janos Follath |
0:fc70c47eecb4 | 184 | mbedtls_ssl_conf_ca_chain(&_ssl_conf, &_cacert, NULL); |
| Janos Follath |
0:fc70c47eecb4 | 185 | mbedtls_ssl_conf_rng(&_ssl_conf, mbedtls_ctr_drbg_random, &_ctr_drbg); |
| Janos Follath |
0:fc70c47eecb4 | 186 | |
| mbed_official | 13:1ae41c231014 | 187 | /* It is possible to disable authentication by passing |
| mbed_official | 13:1ae41c231014 | 188 | * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode() |
| mbed_official | 13:1ae41c231014 | 189 | */ |
| mbed_official | 13:1ae41c231014 | 190 | mbedtls_ssl_conf_authmode(&_ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED); |
| Janos Follath |
0:fc70c47eecb4 | 191 | |
| Janos Follath |
0:fc70c47eecb4 | 192 | #if DEBUG_LEVEL > 0 |
| Janos Follath |
0:fc70c47eecb4 | 193 | mbedtls_ssl_conf_verify(&_ssl_conf, my_verify, NULL); |
| Janos Follath |
0:fc70c47eecb4 | 194 | mbedtls_ssl_conf_dbg(&_ssl_conf, my_debug, NULL); |
| Janos Follath |
0:fc70c47eecb4 | 195 | mbedtls_debug_set_threshold(DEBUG_LEVEL); |
| Janos Follath |
0:fc70c47eecb4 | 196 | #endif |
| Janos Follath |
0:fc70c47eecb4 | 197 | |
| Janos Follath |
0:fc70c47eecb4 | 198 | if ((ret = mbedtls_ssl_setup(&_ssl, &_ssl_conf)) != 0) { |
| Janos Follath |
0:fc70c47eecb4 | 199 | print_mbedtls_error("mbedtls_ssl_setup", ret); |
| Janos Follath |
0:fc70c47eecb4 | 200 | _error = true; |
| Janos Follath |
0:fc70c47eecb4 | 201 | return; |
| Janos Follath |
0:fc70c47eecb4 | 202 | } |
| Janos Follath |
0:fc70c47eecb4 | 203 | |
| Janos Follath |
0:fc70c47eecb4 | 204 | mbedtls_ssl_set_hostname(&_ssl, HTTPS_SERVER_NAME); |
| Janos Follath |
0:fc70c47eecb4 | 205 | |
| Janos Follath |
0:fc70c47eecb4 | 206 | mbedtls_ssl_set_bio(&_ssl, static_cast<void *>(_tcpsocket), |
| Janos Follath |
0:fc70c47eecb4 | 207 | ssl_send, ssl_recv, NULL ); |
| Janos Follath |
0:fc70c47eecb4 | 208 | |
| Janos Follath |
0:fc70c47eecb4 | 209 | |
| Janos Follath |
0:fc70c47eecb4 | 210 | /* Connect to the server */ |
| Janos Follath |
0:fc70c47eecb4 | 211 | mbedtls_printf("Connecting with %s\r\n", _domain); |
| mbed_official | 13:1ae41c231014 | 212 | ret = _tcpsocket->connect(_domain, _port); |
| JMF | 16:3bac55ad2049 | 213 | _tcpsocket->set_blocking (false,1500); |
| JMF | 16:3bac55ad2049 | 214 | |
| Janos Follath |
0:fc70c47eecb4 | 215 | /* Start the handshake, the rest will be done in onReceive() */ |
| Janos Follath |
0:fc70c47eecb4 | 216 | mbedtls_printf("Starting the TLS handshake...\r\n"); |
| Janos Follath |
0:fc70c47eecb4 | 217 | ret = mbedtls_ssl_handshake(&_ssl); |
| Janos Follath |
0:fc70c47eecb4 | 218 | if (ret < 0) { |
| Janos Follath |
0:fc70c47eecb4 | 219 | if (ret != MBEDTLS_ERR_SSL_WANT_READ && |
| Janos Follath |
0:fc70c47eecb4 | 220 | ret != MBEDTLS_ERR_SSL_WANT_WRITE) { |
| Janos Follath |
0:fc70c47eecb4 | 221 | print_mbedtls_error("mbedtls_ssl_handshake", ret); |
| Janos Follath |
0:fc70c47eecb4 | 222 | onError(_tcpsocket, -1 ); |
| Janos Follath |
0:fc70c47eecb4 | 223 | } |
| Janos Follath |
0:fc70c47eecb4 | 224 | return; |
| Janos Follath |
0:fc70c47eecb4 | 225 | } |
| Janos Follath |
0:fc70c47eecb4 | 226 | |
| Janos Follath |
0:fc70c47eecb4 | 227 | ret = mbedtls_ssl_write(&_ssl, (const unsigned char *) _buffer, _bpos); |
| Janos Follath |
0:fc70c47eecb4 | 228 | if (ret < 0) { |
| Janos Follath |
0:fc70c47eecb4 | 229 | if (ret != MBEDTLS_ERR_SSL_WANT_READ && |
| Janos Follath |
0:fc70c47eecb4 | 230 | ret != MBEDTLS_ERR_SSL_WANT_WRITE) { |
| Janos Follath |
0:fc70c47eecb4 | 231 | print_mbedtls_error("mbedtls_ssl_write", ret); |
| Janos Follath |
0:fc70c47eecb4 | 232 | onError(_tcpsocket, -1 ); |
| Janos Follath |
0:fc70c47eecb4 | 233 | } |
| Janos Follath |
0:fc70c47eecb4 | 234 | return; |
| Janos Follath |
0:fc70c47eecb4 | 235 | } |
| Janos Follath |
0:fc70c47eecb4 | 236 | |
| Janos Follath |
0:fc70c47eecb4 | 237 | /* It also means the handshake is done, time to print info */ |
| JMF | 16:3bac55ad2049 | 238 | mbedtls_printf("TLS connection to %s established\r\n", HTTPS_SERVER_NAME); |
| Janos Follath |
0:fc70c47eecb4 | 239 | |
| mbed_official | 9:1ac74f2d7bda | 240 | const uint32_t buf_size = 1024; |
| mbed_official | 9:1ac74f2d7bda | 241 | char *buf = new char[buf_size]; |
| mbed_official | 9:1ac74f2d7bda | 242 | mbedtls_x509_crt_info(buf, buf_size, "\r ", |
| Janos Follath |
0:fc70c47eecb4 | 243 | mbedtls_ssl_get_peer_cert(&_ssl)); |
| Janos Follath |
0:fc70c47eecb4 | 244 | mbedtls_printf("Server certificate:\r\n%s\r", buf); |
| Janos Follath |
0:fc70c47eecb4 | 245 | |
| Janos Follath |
0:fc70c47eecb4 | 246 | uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl); |
| Janos Follath |
0:fc70c47eecb4 | 247 | if( flags != 0 ) |
| Janos Follath |
0:fc70c47eecb4 | 248 | { |
| mbed_official | 9:1ac74f2d7bda | 249 | mbedtls_x509_crt_verify_info(buf, buf_size, "\r ! ", flags); |
| JMF | 16:3bac55ad2049 | 250 | mbedtls_printf("Certificate verification failed:\r\n%s\r\r\n", buf); |
| Janos Follath |
0:fc70c47eecb4 | 251 | } |
| Janos Follath |
0:fc70c47eecb4 | 252 | else |
| JMF | 16:3bac55ad2049 | 253 | mbedtls_printf("Certificate verification passed\r\n\r\n"); |
| Janos Follath |
0:fc70c47eecb4 | 254 | |
| Janos Follath |
0:fc70c47eecb4 | 255 | |
| Janos Follath |
0:fc70c47eecb4 | 256 | /* Read data out of the socket */ |
| Janos Follath |
0:fc70c47eecb4 | 257 | ret = mbedtls_ssl_read(&_ssl, (unsigned char *) _buffer, sizeof(_buffer)); |
| Janos Follath |
0:fc70c47eecb4 | 258 | if (ret < 0) { |
| Janos Follath |
0:fc70c47eecb4 | 259 | if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { |
| Janos Follath |
0:fc70c47eecb4 | 260 | print_mbedtls_error("mbedtls_ssl_read", ret); |
| Janos Follath |
0:fc70c47eecb4 | 261 | onError(_tcpsocket, -1 ); |
| Janos Follath |
0:fc70c47eecb4 | 262 | } |
| mbed_official | 9:1ac74f2d7bda | 263 | delete[] buf; |
| Janos Follath |
0:fc70c47eecb4 | 264 | return; |
| Janos Follath |
0:fc70c47eecb4 | 265 | } |
| Janos Follath |
0:fc70c47eecb4 | 266 | _bpos = static_cast<size_t>(ret); |
| Janos Follath |
0:fc70c47eecb4 | 267 | |
| Janos Follath |
0:fc70c47eecb4 | 268 | _buffer[_bpos] = 0; |
| Janos Follath |
0:fc70c47eecb4 | 269 | |
| Janos Follath |
0:fc70c47eecb4 | 270 | /* Check each of the flags */ |
| Janos Follath |
0:fc70c47eecb4 | 271 | _got200 = _got200 || strstr(_buffer, HTTPS_OK_STR) != NULL; |
| Janos Follath |
0:fc70c47eecb4 | 272 | _gothello = _gothello || strstr(_buffer, HTTPS_HELLO_STR) != NULL; |
| Janos Follath |
0:fc70c47eecb4 | 273 | |
| Janos Follath |
0:fc70c47eecb4 | 274 | /* Print status messages */ |
| Janos Follath |
0:fc70c47eecb4 | 275 | mbedtls_printf("HTTPS: Received %d chars from server\r\n", _bpos); |
| Janos Follath |
0:fc70c47eecb4 | 276 | mbedtls_printf("HTTPS: Received 200 OK status ... %s\r\n", _got200 ? "[OK]" : "[FAIL]"); |
| Janos Follath |
0:fc70c47eecb4 | 277 | mbedtls_printf("HTTPS: Received '%s' status ... %s\r\n", HTTPS_HELLO_STR, _gothello ? "[OK]" : "[FAIL]"); |
| Janos Follath |
0:fc70c47eecb4 | 278 | mbedtls_printf("HTTPS: Received message:\r\n\r\n"); |
| Janos Follath |
0:fc70c47eecb4 | 279 | mbedtls_printf("%s", _buffer); |
| Janos Follath |
0:fc70c47eecb4 | 280 | _error = !(_got200 && _gothello); |
| Janos Follath |
0:fc70c47eecb4 | 281 | |
| Janos Follath |
0:fc70c47eecb4 | 282 | _tcpsocket->close(); |
| mbed_official | 9:1ac74f2d7bda | 283 | delete[] buf; |
| Janos Follath |
0:fc70c47eecb4 | 284 | } |
| Janos Follath |
0:fc70c47eecb4 | 285 | protected: |
| Janos Follath |
0:fc70c47eecb4 | 286 | /** |
| Janos Follath |
0:fc70c47eecb4 | 287 | * Helper for pretty-printing mbed TLS error codes |
| Janos Follath |
0:fc70c47eecb4 | 288 | */ |
| Janos Follath |
0:fc70c47eecb4 | 289 | static void print_mbedtls_error(const char *name, int err) { |
| Janos Follath |
0:fc70c47eecb4 | 290 | char buf[128]; |
| Janos Follath |
0:fc70c47eecb4 | 291 | mbedtls_strerror(err, buf, sizeof (buf)); |
| Janos Follath |
0:fc70c47eecb4 | 292 | mbedtls_printf("%s() failed: -0x%04x (%d): %s\r\n", name, -err, err, buf); |
| Janos Follath |
0:fc70c47eecb4 | 293 | } |
| Janos Follath |
0:fc70c47eecb4 | 294 | |
| Janos Follath |
0:fc70c47eecb4 | 295 | #if DEBUG_LEVEL > 0 |
| Janos Follath |
0:fc70c47eecb4 | 296 | /** |
| Janos Follath |
0:fc70c47eecb4 | 297 | * Debug callback for mbed TLS |
| Janos Follath |
0:fc70c47eecb4 | 298 | * Just prints on the USB serial port |
| Janos Follath |
0:fc70c47eecb4 | 299 | */ |
| Janos Follath |
0:fc70c47eecb4 | 300 | static void my_debug(void *ctx, int level, const char *file, int line, |
| Janos Follath |
0:fc70c47eecb4 | 301 | const char *str) |
| Janos Follath |
0:fc70c47eecb4 | 302 | { |
| Janos Follath |
0:fc70c47eecb4 | 303 | const char *p, *basename; |
| Janos Follath |
0:fc70c47eecb4 | 304 | (void) ctx; |
| Janos Follath |
0:fc70c47eecb4 | 305 | |
| Janos Follath |
0:fc70c47eecb4 | 306 | /* Extract basename from file */ |
| Janos Follath |
0:fc70c47eecb4 | 307 | for(p = basename = file; *p != '\0'; p++) { |
| Janos Follath |
0:fc70c47eecb4 | 308 | if(*p == '/' || *p == '\\') { |
| Janos Follath |
0:fc70c47eecb4 | 309 | basename = p + 1; |
| Janos Follath |
0:fc70c47eecb4 | 310 | } |
| Janos Follath |
0:fc70c47eecb4 | 311 | } |
| Janos Follath |
0:fc70c47eecb4 | 312 | |
| Janos Follath |
0:fc70c47eecb4 | 313 | mbedtls_printf("%s:%04d: |%d| %s", basename, line, level, str); |
| Janos Follath |
0:fc70c47eecb4 | 314 | } |
| Janos Follath |
0:fc70c47eecb4 | 315 | |
| Janos Follath |
0:fc70c47eecb4 | 316 | /** |
| Janos Follath |
0:fc70c47eecb4 | 317 | * Certificate verification callback for mbed TLS |
| Janos Follath |
0:fc70c47eecb4 | 318 | * Here we only use it to display information on each cert in the chain |
| Janos Follath |
0:fc70c47eecb4 | 319 | */ |
| Janos Follath |
0:fc70c47eecb4 | 320 | static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) |
| Janos Follath |
0:fc70c47eecb4 | 321 | { |
| mbed_official | 9:1ac74f2d7bda | 322 | const uint32_t buf_size = 1024; |
| mbed_official | 9:1ac74f2d7bda | 323 | char *buf = new char[buf_size]; |
| Janos Follath |
0:fc70c47eecb4 | 324 | (void) data; |
| Janos Follath |
0:fc70c47eecb4 | 325 | |
| Janos Follath |
0:fc70c47eecb4 | 326 | mbedtls_printf("\nVerifying certificate at depth %d:\n", depth); |
| mbed_official | 9:1ac74f2d7bda | 327 | mbedtls_x509_crt_info(buf, buf_size - 1, " ", crt); |
| Janos Follath |
0:fc70c47eecb4 | 328 | mbedtls_printf("%s", buf); |
| Janos Follath |
0:fc70c47eecb4 | 329 | |
| Janos Follath |
0:fc70c47eecb4 | 330 | if (*flags == 0) |
| Janos Follath |
0:fc70c47eecb4 | 331 | mbedtls_printf("No verification issue for this certificate\n"); |
| Janos Follath |
0:fc70c47eecb4 | 332 | else |
| Janos Follath |
0:fc70c47eecb4 | 333 | { |
| mbed_official | 9:1ac74f2d7bda | 334 | mbedtls_x509_crt_verify_info(buf, buf_size, " ! ", *flags); |
| Janos Follath |
0:fc70c47eecb4 | 335 | mbedtls_printf("%s\n", buf); |
| Janos Follath |
0:fc70c47eecb4 | 336 | } |
| Janos Follath |
0:fc70c47eecb4 | 337 | |
| mbed_official | 9:1ac74f2d7bda | 338 | delete[] buf; |
| Janos Follath |
0:fc70c47eecb4 | 339 | return 0; |
| Janos Follath |
0:fc70c47eecb4 | 340 | } |
| Janos Follath |
0:fc70c47eecb4 | 341 | #endif |
| Janos Follath |
0:fc70c47eecb4 | 342 | |
| Janos Follath |
0:fc70c47eecb4 | 343 | /** |
| Janos Follath |
0:fc70c47eecb4 | 344 | * Receive callback for mbed TLS |
| Janos Follath |
0:fc70c47eecb4 | 345 | */ |
| Janos Follath |
0:fc70c47eecb4 | 346 | static int ssl_recv(void *ctx, unsigned char *buf, size_t len) { |
| JMF | 16:3bac55ad2049 | 347 | TCPSocketConnection *socket = static_cast<TCPSocketConnection *>(ctx); |
| JMF | 16:3bac55ad2049 | 348 | return (int)socket->receive((char*)buf, len); |
| Janos Follath |
0:fc70c47eecb4 | 349 | } |
| Janos Follath |
0:fc70c47eecb4 | 350 | |
| Janos Follath |
0:fc70c47eecb4 | 351 | /** |
| Janos Follath |
0:fc70c47eecb4 | 352 | * Send callback for mbed TLS |
| Janos Follath |
0:fc70c47eecb4 | 353 | */ |
| Janos Follath |
0:fc70c47eecb4 | 354 | static int ssl_send(void *ctx, const unsigned char *buf, size_t len) { |
| JMF | 16:3bac55ad2049 | 355 | TCPSocketConnection *socket = static_cast<TCPSocketConnection *>(ctx); |
| JMF | 16:3bac55ad2049 | 356 | return socket->send((char*)buf, len); |
| Janos Follath |
0:fc70c47eecb4 | 357 | } |
| Janos Follath |
0:fc70c47eecb4 | 358 | |
| JMF | 16:3bac55ad2049 | 359 | void onError(TCPSocketConnection *s, int error) { |
| JMF | 16:3bac55ad2049 | 360 | mbedtls_printf("MBED: Socket Error: %d\r\n", error); |
| Janos Follath |
0:fc70c47eecb4 | 361 | s->close(); |
| Janos Follath |
0:fc70c47eecb4 | 362 | _error = true; |
| Janos Follath |
0:fc70c47eecb4 | 363 | } |
| Janos Follath |
0:fc70c47eecb4 | 364 | |
| Janos Follath |
0:fc70c47eecb4 | 365 | protected: |
| JMF | 16:3bac55ad2049 | 366 | TCPSocketConnection* _tcpsocket; |
| Janos Follath |
0:fc70c47eecb4 | 367 | |
| Janos Follath |
0:fc70c47eecb4 | 368 | const char *_domain; /**< The domain name of the HTTPS server */ |
| Janos Follath |
0:fc70c47eecb4 | 369 | const uint16_t _port; /**< The HTTPS server port */ |
| Janos Follath |
0:fc70c47eecb4 | 370 | char _buffer[RECV_BUFFER_SIZE]; /**< The response buffer */ |
| Janos Follath |
0:fc70c47eecb4 | 371 | size_t _bpos; /**< The current offset in the response buffer */ |
| Janos Follath |
0:fc70c47eecb4 | 372 | volatile bool _got200; /**< Status flag for HTTPS 200 */ |
| Janos Follath |
0:fc70c47eecb4 | 373 | volatile bool _gothello; /**< Status flag for finding the test string */ |
| Janos Follath |
0:fc70c47eecb4 | 374 | volatile bool _error; /**< Status flag for an error */ |
| Janos Follath |
0:fc70c47eecb4 | 375 | volatile bool _disconnected; |
| Janos Follath |
0:fc70c47eecb4 | 376 | volatile bool _request_sent; |
| Janos Follath |
0:fc70c47eecb4 | 377 | |
| Janos Follath |
0:fc70c47eecb4 | 378 | mbedtls_entropy_context _entropy; |
| Janos Follath |
0:fc70c47eecb4 | 379 | mbedtls_ctr_drbg_context _ctr_drbg; |
| Janos Follath |
0:fc70c47eecb4 | 380 | mbedtls_x509_crt _cacert; |
| Janos Follath |
0:fc70c47eecb4 | 381 | mbedtls_ssl_context _ssl; |
| Janos Follath |
0:fc70c47eecb4 | 382 | mbedtls_ssl_config _ssl_conf; |
| Janos Follath |
0:fc70c47eecb4 | 383 | }; |
| Janos Follath |
0:fc70c47eecb4 | 384 | |
| JMF | 16:3bac55ad2049 | 385 | MODSERIAL pc(USBTX,USBRX,256,256); |
| JMF | 16:3bac55ad2049 | 386 | |
| JMF | 16:3bac55ad2049 | 387 | #ifdef __cplusplus |
| JMF | 16:3bac55ad2049 | 388 | extern "C" { |
| JMF | 16:3bac55ad2049 | 389 | #endif |
| JMF | 16:3bac55ad2049 | 390 | |
| JMF | 16:3bac55ad2049 | 391 | int myprintf( const char* format, ... ) { |
| JMF | 16:3bac55ad2049 | 392 | extern MODSERIAL pc; |
| JMF | 16:3bac55ad2049 | 393 | string buff; |
| JMF | 16:3bac55ad2049 | 394 | |
| JMF | 16:3bac55ad2049 | 395 | va_list valist; |
| JMF | 16:3bac55ad2049 | 396 | buff.reserve(2048); |
| JMF | 16:3bac55ad2049 | 397 | va_start(valist, format); |
| JMF | 16:3bac55ad2049 | 398 | vsprintf(&buff[0],format,valist); |
| JMF | 16:3bac55ad2049 | 399 | pc.puts(buff.c_str()); |
| JMF | 16:3bac55ad2049 | 400 | va_end(valist); |
| JMF | 16:3bac55ad2049 | 401 | return 0; |
| JMF | 16:3bac55ad2049 | 402 | } |
| JMF | 16:3bac55ad2049 | 403 | |
| JMF | 16:3bac55ad2049 | 404 | #ifdef __cplusplus |
| JMF | 16:3bac55ad2049 | 405 | } |
| JMF | 16:3bac55ad2049 | 406 | #endif |
| Janos Follath |
0:fc70c47eecb4 | 407 | /** |
| Janos Follath |
0:fc70c47eecb4 | 408 | * The main loop of the HTTPS Hello World test |
| Janos Follath |
0:fc70c47eecb4 | 409 | */ |
| Janos Follath |
0:fc70c47eecb4 | 410 | int main() { |
| JMF | 16:3bac55ad2049 | 411 | int ret; |
| Janos Follath |
0:fc70c47eecb4 | 412 | /* The default 9600 bps is too slow to print full TLS debug info and could |
| Janos Follath |
0:fc70c47eecb4 | 413 | * cause the other party to time out. */ |
| Janos Follath |
0:fc70c47eecb4 | 414 | |
| Janos Follath |
0:fc70c47eecb4 | 415 | /* Inititalise with DHCP, connect, and start up the stack */ |
| JMF | 16:3bac55ad2049 | 416 | WNCInterface eth_iface; |
| JMF | 16:3bac55ad2049 | 417 | |
| JMF | 16:3bac55ad2049 | 418 | pc.baud(115200); |
| JMF | 16:3bac55ad2049 | 419 | pc.printf(CRLF "Starting HTTPS File Download Example for TLS use WNC Data Module" CRLF); |
| JMF | 16:3bac55ad2049 | 420 | |
| JMF | 16:3bac55ad2049 | 421 | ret = eth_iface.init(NULL, &pc); |
| JMF | 16:3bac55ad2049 | 422 | pc.printf("WNC Module %s initialized (%02X)." CRLF, ret?"IS":"IS NOT", ret); |
| JMF | 16:3bac55ad2049 | 423 | if( !ret ) { |
| JMF | 16:3bac55ad2049 | 424 | pc.printf(" - - - - - - - ALL DONE - - - - - - - " CRLF); |
| JMF | 16:3bac55ad2049 | 425 | while(1); |
| JMF | 16:3bac55ad2049 | 426 | } |
| JMF | 16:3bac55ad2049 | 427 | |
| Janos Follath |
0:fc70c47eecb4 | 428 | eth_iface.connect(); |
| JMF | 16:3bac55ad2049 | 429 | pc.printf("IP Address: %s " CRLF CRLF, eth_iface.getIPAddress()); |
| Janos Follath |
0:fc70c47eecb4 | 430 | |
| mbed_official | 9:1ac74f2d7bda | 431 | HelloHTTPS *hello = new HelloHTTPS(HTTPS_SERVER_NAME, HTTPS_SERVER_PORT, ð_iface); |
| mbed_official | 9:1ac74f2d7bda | 432 | hello->startTest(HTTPS_PATH); |
| JMF | 16:3bac55ad2049 | 433 | pc.printf(" >>> DONE <<<\r\n"); |
| mbed_official | 9:1ac74f2d7bda | 434 | delete hello; |
| Janos Follath |
0:fc70c47eecb4 | 435 | } |