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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HelloHttpsClient.h Source File

HelloHttpsClient.h

00001 /*
00002  *  Hello world example of a TLS client: fetch an HTTPS page
00003  *
00004  *  Copyright (C) 2006-2018, Arm Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of Mbed TLS (https://tls.mbed.org)
00020  */
00021 
00022 #ifndef _HELLOHTTPSCLIENT_H_
00023 #define _HELLOHTTPSCLIENT_H_
00024 
00025 #include "TCPSocket.h"
00026 
00027 #include "mbedtls/config.h"
00028 #include "mbedtls/ssl.h"
00029 #include "mbedtls/entropy.h"
00030 #include "mbedtls/ctr_drbg.h"
00031 #include "mbedtls/error.h"
00032 #include "mbedtls/debug.h"
00033 
00034 #include <stdint.h>
00035 
00036 /**
00037  * Change to a number between 1 and 4 to debug the TLS connection
00038  */
00039 #define HELLO_HTTPS_CLIENT_DEBUG_LEVEL  0
00040 
00041 /**
00042  * Length (in bytes) for generic buffers used to hold debug or HTTP
00043  * request/response strings
00044  */
00045 #define GENERAL_PURPOSE_BUFFER_LENGTH   1024
00046 
00047 /**
00048  * This class implements the logic for fetching a file from a webserver using
00049  * a TCP socket and parsing the result.
00050  */
00051 class HelloHttpsClient
00052 {
00053 public:
00054     /**
00055      * Construct an HelloHttpsClient instance
00056      *
00057      * \param[in]   in_server_name
00058      *              The server host name
00059      * \param[in]   in_server_addr
00060      *              The server domain/IP address
00061      * \param[in]   in_server_port
00062      *              The server port
00063      */
00064     HelloHttpsClient(const char *in_server_name,
00065                      const char *in_server_addr,
00066                      const uint16_t in_server_port);
00067 
00068     /**
00069      * Free any allocated resources
00070      */
00071     ~HelloHttpsClient();
00072 
00073     /**
00074      * Start the connection to the server and request to read the file at
00075      * HTTP_REQUEST_FILE_PATH
00076      *
00077      * \return  0 if successful
00078      */
00079     int run();
00080 
00081 private:
00082     /**
00083      * Create a TCPSocket object that can be used to communicate with the server
00084      */
00085     int configureTCPSocket();
00086 
00087     /**
00088      * Configure the Mbed TLS structures required to establish a TLS connection
00089      * with the server
00090      */
00091     int configureTlsContexts();
00092 
00093     /**
00094      * Wrapper function around TCPSocket that gets called by Mbed TLS whenever
00095      * we call mbedtls_ssl_read()
00096      *
00097      * \param[in]   ctx
00098      *              The TCPSocket object
00099      * \param[in]   buf
00100      *              Buffer where data received will be stored
00101      * \param[in]   len
00102      *              The length (in bytes) of the buffer
00103      *
00104      * \return  If successful, the number of bytes received, a negative value
00105      *          otherwise.
00106      */
00107     static int sslRecv(void *ctx, unsigned char *buf, size_t len);
00108 
00109     /**
00110      * Wrapper function around TCPSocket that gets called by Mbed TLS whenever
00111      * we call mbedtls_ssl_write()
00112      *
00113      * \param[in]   ctx
00114      *              The TCPSocket object
00115      * \param[in]   buf
00116      *              Buffer containing the data to be sent
00117      * \param[in]   len
00118      *              The number of bytes to send
00119      *
00120      * \return  If successful, the number of bytes sent, a negative value
00121      *          otherwise
00122      */
00123     static int sslSend(void *ctx, const unsigned char *buf, size_t len);
00124 
00125     /**
00126      * Callback to handle debug prints to serial
00127      *
00128      * \param[in]   ctx
00129      *              The context (unused in this case)
00130      * \param[in]   level
00131      *              The current debug level
00132      * \param[in]   file
00133      *              The C file that is logging this message
00134      * \param[in]   line
00135      *              The line number in the file
00136      * \param[in]   str
00137      *              The string to log to serial
00138      */
00139     static void sslDebug(void *ctx, int level, const char *file, int line,
00140                          const char *str);
00141 
00142     /**
00143      * Callback to handle certificate verification
00144      *
00145      * /param[in]       data
00146      *                  (unused)
00147      * /param[in]       crt
00148      *                  The crt in the chain that we are verifying
00149      * /param[in]       depth
00150      *                  The depth of the current certificate in the chain
00151      * /param[in/out]   flags
00152      *                  The flags resulting from the verification
00153      *
00154      * /return  0 if successful
00155      */
00156     static int sslVerify(void *ctx, mbedtls_x509_crt *crt, int depth,
00157                          uint32_t *flags);
00158 
00159 private:
00160     /**
00161      * Personalization string for the drbg
00162      */
00163     static const char *DRBG_PERSONALIZED_STR;
00164 
00165     /**
00166      *  Length of error string buffer for logging failures related to Mbed TLS
00167      */
00168     static const size_t ERROR_LOG_BUFFER_LENGTH;
00169 
00170     /**
00171      * Chain of trusted CAs in PEM format
00172      */
00173     static const char *TLS_PEM_CA;
00174 
00175     /**
00176      * Path to the file that will be requested from the server
00177      */
00178     static const char *HTTP_REQUEST_FILE_PATH;
00179 
00180     /**
00181      * Expected strings in the HTTP response from the server
00182      */
00183     static const char *HTTP_OK_STR;
00184 
00185     /**
00186      * Expected strings in the HTTP response from the server
00187      */
00188     static const char *HTTP_HELLO_STR;
00189 
00190     /**
00191      * Instance of TCPSocket used to communicate with the server
00192      */
00193     TCPSocket socket;
00194 
00195     /**
00196      * The server host name to contact
00197      */
00198     const char *server_name;
00199 
00200     /**
00201      * The domain/IP address of the server to contact
00202      */
00203     const char *server_addr;
00204     /**
00205      * The port number to use in the connection
00206      */
00207     const uint16_t server_port;
00208 
00209     /**
00210      * A generic buffer used to hold debug or HTTP request/response strings
00211      */
00212     char gp_buf[GENERAL_PURPOSE_BUFFER_LENGTH];
00213 
00214     /**
00215      * Entropy context used to seed the DRBG to use in the TLS connection
00216      */
00217     mbedtls_entropy_context entropy;
00218     /**
00219      * The DRBG used throughout the TLS connection
00220      */
00221     mbedtls_ctr_drbg_context ctr_drbg;
00222     /**
00223      * The parsed chain of trusted CAs
00224      */
00225     mbedtls_x509_crt cacert;
00226     /**
00227      * THe TLS context
00228      */
00229     mbedtls_ssl_context ssl;
00230     /**
00231      * The TLS configuration in use
00232      */
00233     mbedtls_ssl_config ssl_conf;
00234 };
00235 
00236 #endif /* _HELLOHTTPSCLIENT_H_ */