Example usage of mbed tls library for HTTPS interactions.
Dependencies: WNCInterface mbed-rtos mbed
Revision 16:3bac55ad2049, committed 2016-11-02
- Comitter:
- JMF
- Date:
- Wed Nov 02 19:20:20 2016 +0000
- Parent:
- 15:339320b096c5
- Child:
- 17:a5a672bc0ac0
- Commit message:
- An example program showing how to perform HTTPS interactions.
Changed in this revision
--- a/README.md Fri Oct 28 13:30:20 2016 +0100
+++ b/README.md Wed Nov 02 19:20:20 2016 +0000
@@ -1,28 +1,38 @@
-# HTTPS File Download Example for TLS Client on mbed OS
+==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
+Using the AT&T Cellular IoT Starter Kit from [[http://cloudconnectkits.org/product/att-cellular-iot-starter-kit|Avnet]]
+the this program downloads a file from an HTTPS server (developer.mbed.org) and looks for a specific string
+in that file.
-Set up your environment if you have not done so already. For instructions, refer to the [main readme](../README.md).
+**NOTE**:
+This doc is specific to using the AT&T Cellular IoT Starter Kit which contains a
+[[https://developer.mbed.org/platforms/FRDM-K64F/|FRDM-K64F]] from NXP. Ensure that the
+[[https://mbed.org/compiler/|mbed online compiler]] has the platform set to FRDM-K64F.
-## Required hardware
+1. Launch [[https://mbed.org/compiler/|mbed online compiler]] in your browser
-This example also requires an Ethernet cable and connection to the internet additional to the hardware requirements in the [main readme](../README.md).
+2. In a seperate browser Tab, goto the [[https://developer.mbed.org/teams/Avnet/code/BluemixQS/|Avnet BluemixQS]] site and select the
+ **Import into Compiler** button in the upper right portion of the window.
+
+3. With the example program imported into you work-space, you have all the components needed. Simply execute the **Compile** button.
-The networking stack used in this example requires TLS functionality to be enabled on mbed TLS. On devices where hardware entropy is not present, TLS is disabled by default. This would result in compile time or linking failures.
+
+==Expected execution outcome==
-To learn why entropy is required, read the [TLS Porting guide](https://docs.mbed.com/docs/mbed-os-handbook/en/5.2/advanced/tls_porting/).
+Once the program is compiled and downloaded to the IoT Kit, perform the following steps:
-## Monitoring the application
+1. Using a terminal program such as Hyperterm or Putty, connect to the Kit (select comm parameters of 115200-N81)
+
+2. Press the `reset` button, then you should see the program start running! When it runs, the output will look similar to:
-__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:
+<<code title=Sample Ouput>>
+Starting HTTPS File Download Example for TLS use WNC Data Module
-```
-Using Ethernet LWIP
-Client IP Address is 10.2.203.43
+Toggling Wakeup...
+Toggling complete.
+WNC Module IS initialized (07).
+IP Address: 10.63.211.229
+
Connecting with developer.mbed.org
Starting the TLS handshake...
TLS connection to developer.mbed.org established
@@ -48,26 +58,36 @@
HTTP/1.1 200 OK
Server: nginx/1.7.10
-Date: Wed, 20 Jul 2016 10:00:35 GMT
+Date: Wed, 02 Nov 2016 19:05:55 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
+Expires: Thu, 03 Nov 2016 05:05:55 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!
-```
+ >>> DONE <<<
+<</code>>
-## Debugging the TLS connection
+==Required Configuration changes==
+The networking stack in this example uses TLS functionality. On devices where hardware entropy
+is not present, TLS is disabled by default. This example is not suitable for a productg code
+and the configuration setting are for demonstration purposes.
-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:
+To learn more about entropy read:
+the [TLS Porting guide](https://docs.mbed.com/docs/mbed-os-handbook/en/5.2/advanced/tls_porting/).
-* Level 1 only prints non-zero return codes from SSL functions and information about the full certificate chain being verified.
+==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.
@@ -78,12 +98,29 @@
The TLS connection can fail with an error similar to:
- mbedtls_ssl_write() failed: -0x2700 (-9984): X509 - Certificate verification failed, e.g. CRL, CA or signature check failed
+ 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).
+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.
+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!
+==License==
+This library is released under the Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+file except in compliance with the License and may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+
+Set up your environment if you have not done so already. For instructions, refer to the [main readme](../README.md).
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WNCInterface.lib Wed Nov 02 19:20:20 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/Avnet/code/WNCInterface/#efb742130cb2
--- a/main.cpp Fri Oct 28 13:30:20 2016 +0100
+++ b/main.cpp Wed Nov 02 19:20:20 2016 +0000
@@ -33,10 +33,10 @@
#define DEBUG_LEVEL 0
#include "mbed.h"
-#include "NetworkStack.h"
+//#include "NetworkStack.h"
-#include "EthernetInterface.h"
-#include "TCPSocket.h"
+#include "WNCInterface.h"
+#include "TCPSocketConnection.h"
#include "mbedtls/platform.h"
#include "mbedtls/ssl.h"
@@ -44,6 +44,8 @@
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
+#define CRLF "\r\n"
+
#if DEBUG_LEVEL > 0
#include "mbedtls/debug.h"
#endif
@@ -55,7 +57,7 @@
const int RECV_BUFFER_SIZE = 600;
const char HTTPS_PATH[] = "/media/uploads/mbed_official/hello.txt";
-const size_t HTTPS_PATH_LEN = sizeof(HTTPS_PATH) - 1;
+//const size_t HTTPS_PATH_LEN = sizeof(HTTPS_PATH) - 1;
/* Test related data */
const char *HTTPS_OK_STR = "200 OK";
@@ -106,7 +108,7 @@
* @param[in] domain The domain name to fetch from
* @param[in] port The port of the HTTPS server
*/
- HelloHTTPS(const char * domain, const uint16_t port, NetworkInterface *net_iface) :
+ HelloHTTPS(const char * domain, const uint16_t port, WNCInterface *net_iface) :
_domain(domain), _port(port)
{
@@ -115,7 +117,7 @@
_got200 = false;
_bpos = 0;
_request_sent = 0;
- _tcpsocket = new TCPSocket(net_iface);
+ _tcpsocket = new TCPSocketConnection;
mbedtls_entropy_init(&_entropy);
mbedtls_ctr_drbg_init(&_ctr_drbg);
@@ -208,12 +210,8 @@
/* Connect to the server */
mbedtls_printf("Connecting with %s\r\n", _domain);
ret = _tcpsocket->connect(_domain, _port);
- if (ret != NSAPI_ERROR_OK) {
- mbedtls_printf("Failed to connect\r\n");
- onError(_tcpsocket, -1);
- return;
- }
-
+ _tcpsocket->set_blocking (false,1500);
+
/* Start the handshake, the rest will be done in onReceive() */
mbedtls_printf("Starting the TLS handshake...\r\n");
ret = mbedtls_ssl_handshake(&_ssl);
@@ -237,7 +235,7 @@
}
/* It also means the handshake is done, time to print info */
- printf("TLS connection to %s established\r\n", HTTPS_SERVER_NAME);
+ mbedtls_printf("TLS connection to %s established\r\n", HTTPS_SERVER_NAME);
const uint32_t buf_size = 1024;
char *buf = new char[buf_size];
@@ -249,10 +247,10 @@
if( flags != 0 )
{
mbedtls_x509_crt_verify_info(buf, buf_size, "\r ! ", flags);
- printf("Certificate verification failed:\r\n%s\r\r\n", buf);
+ mbedtls_printf("Certificate verification failed:\r\n%s\r\r\n", buf);
}
else
- printf("Certificate verification passed\r\n\r\n");
+ mbedtls_printf("Certificate verification passed\r\n\r\n");
/* Read data out of the socket */
@@ -284,28 +282,6 @@
_tcpsocket->close();
delete[] buf;
}
- /**
- * Check if the test has completed.
- * @return Returns true if done, false otherwise.
- */
- bool done() {
- return _error || (_got200 && _gothello);
- }
- /**
- * Check if there was an error
- * @return Returns true if there was an error, false otherwise.
- */
- bool error() {
- return _error;
- }
- /**
- * Closes the TCP socket
- */
- void close() {
- _tcpsocket->close();
- while (!_disconnected)
- __WFI();
- }
protected:
/**
* Helper for pretty-printing mbed TLS error codes
@@ -368,44 +344,26 @@
* Receive callback for mbed TLS
*/
static int ssl_recv(void *ctx, unsigned char *buf, size_t len) {
- int recv = -1;
- TCPSocket *socket = static_cast<TCPSocket *>(ctx);
- recv = socket->recv(buf, len);
-
- if(NSAPI_ERROR_WOULD_BLOCK == recv){
- return MBEDTLS_ERR_SSL_WANT_READ;
- }else if(recv < 0){
- return -1;
- }else{
- return recv;
- }
+ TCPSocketConnection *socket = static_cast<TCPSocketConnection *>(ctx);
+ return (int)socket->receive((char*)buf, len);
}
/**
* Send callback for mbed TLS
*/
static int ssl_send(void *ctx, const unsigned char *buf, size_t len) {
- int size = -1;
- TCPSocket *socket = static_cast<TCPSocket *>(ctx);
- size = socket->send(buf, len);
-
- if(NSAPI_ERROR_WOULD_BLOCK == size){
- return len;
- }else if(size < 0){
- return -1;
- }else{
- return size;
- }
+ TCPSocketConnection *socket = static_cast<TCPSocketConnection *>(ctx);
+ return socket->send((char*)buf, len);
}
- void onError(TCPSocket *s, int error) {
- printf("MBED: Socket Error: %d\r\n", error);
+ void onError(TCPSocketConnection *s, int error) {
+ mbedtls_printf("MBED: Socket Error: %d\r\n", error);
s->close();
_error = true;
}
protected:
- TCPSocket* _tcpsocket;
+ TCPSocketConnection* _tcpsocket;
const char *_domain; /**< The domain name of the HTTPS server */
const uint16_t _port; /**< The HTTPS server port */
@@ -424,25 +382,54 @@
mbedtls_ssl_config _ssl_conf;
};
+MODSERIAL pc(USBTX,USBRX,256,256);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int myprintf( const char* format, ... ) {
+ extern MODSERIAL pc;
+ string buff;
+
+ va_list valist;
+ buff.reserve(2048);
+ va_start(valist, format);
+ vsprintf(&buff[0],format,valist);
+ pc.puts(buff.c_str());
+ va_end(valist);
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
/**
* The main loop of the HTTPS Hello World test
*/
int main() {
+ int ret;
/* The default 9600 bps is too slow to print full TLS debug info and could
* cause the other party to time out. */
/* Inititalise with DHCP, connect, and start up the stack */
- EthernetInterface eth_iface;
+ WNCInterface eth_iface;
+
+ pc.baud(115200);
+ pc.printf(CRLF "Starting HTTPS File Download Example for TLS use WNC Data Module" CRLF);
+
+ ret = eth_iface.init(NULL, &pc);
+ pc.printf("WNC Module %s initialized (%02X)." CRLF, ret?"IS":"IS NOT", ret);
+ if( !ret ) {
+ pc.printf(" - - - - - - - ALL DONE - - - - - - - " CRLF);
+ while(1);
+ }
+
eth_iface.connect();
- mbedtls_printf("Using Ethernet LWIP\r\n");
- const char *ip_addr = eth_iface.get_ip_address();
- if (ip_addr) {
- mbedtls_printf("Client IP Address is %s\r\n", ip_addr);
- } else {
- mbedtls_printf("No Client IP Address\r\n");
- }
+ pc.printf("IP Address: %s " CRLF CRLF, eth_iface.getIPAddress());
HelloHTTPS *hello = new HelloHTTPS(HTTPS_SERVER_NAME, HTTPS_SERVER_PORT, ð_iface);
hello->startTest(HTTPS_PATH);
+ pc.printf(" >>> DONE <<<\r\n");
delete hello;
}
--- a/mbed-os.lib Fri Oct 28 13:30:20 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#e2617cc0e17f5c3fc2bae6a589c9bcfd3d1a717b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Wed Nov 02 19:20:20 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#3da5f554d8bf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Nov 02 19:20:20 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9bcdf88f62b0 \ No newline at end of file