..

Files at this revision

API Documentation at this revision

Comitter:
ImranBilalButt
Date:
Fri Aug 23 13:29:35 2019 +0000
Commit message:
..

Changed in this revision

LICENSE Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
TLSSocket.cpp Show annotated file Show diff for this revision Revisions of this file
TLSSocket.h Show annotated file Show diff for this revision Revisions of this file
TLSSocketWrapper.cpp Show annotated file Show diff for this revision Revisions of this file
TLSSocketWrapper.h Show annotated file Show diff for this revision Revisions of this file
mbed_lib.json Show annotated file Show diff for this revision Revisions of this file
timing_alt.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,144 @@
+# WORK-IN-PROGRESS: TLSSocket
+
+This implementation is based on yet unreleased Abstract socket interfaces currently in Mbed OS master branch.
+This interface will be released in Mbed OS 5.10, but is not yet released in 5.9
+
+More info:
+* https://github.com/ARMmbed/mbed-os-5-docs/pull/610
+* https://github.com/ARMmbed/mbed-os/pull/7192
+
+This library is created based on [mbed-os-example-tls-tls-client](https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-tls-tls-client/) project.
+
+# How to use it
+```
+#include "mbed.h"
+#include "NetworkInterface.h"
+#include "TLSSocket.h"
+
+const char* HOST_NAME = "os.mbed.com";
+const int PORT = 443;
+const char* HTTPS_PATH = "/";
+
+const char* cert = \
+    "-----BEGIN CERTIFICATE-----\n" \
+    "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\n" \
+    "A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n" \
+    "b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\n" \
+    "MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\n" \
+    "YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\n" \
+    "aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\n" \
+    "jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\n" \
+    "xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n" \
+    "1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\n" \
+    "snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\n" \
+    "U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n" \
+    "9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\n" \
+    "BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\n" \
+    "AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\n" \
+    "yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n" \
+    "38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\n" \
+    "AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\n" \
+    "DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\n" \
+    "HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n" \
+    "-----END CERTIFICATE-----";
+
+
+/** Demonstrate download from a HTTP server through abstract socket interface
+ *  Socket can be any connected socket, TCP or TLS
+ */
+int http_get(Socket *socket)
+{
+    const size_t buf_size = 1024;
+    char *buf = new char[buf_size];
+
+    // Send HTTP request
+    /* "Connection: close" header is specified to detect end of the body
+     * contents by connection close notification. If this is not specified,
+     * connection is kept, and need to detect end of the content in another
+     * way.
+     */
+    int len = snprintf(buf, buf_size,
+                "GET %s HTTP/1.1\n"
+                "Host: %s\n"
+                "Connection: close\n"
+                "\n", HTTPS_PATH, HOST_NAME);
+    printf("\n%s", buf);
+    int rc = 0;
+    rc = socket->send(buf, len);
+    if(rc < 0) {
+        printf("send error.\n");
+        return rc;
+    }
+
+    // Receive response from the server
+    while((rc = socket->recv(buf, buf_size - 1)) > 0) {
+        buf[rc] = '\0';
+        printf("%s", buf);
+    }
+    if(rc < 0) {
+        printf("\n! Read failed. err code = %d\n", rc);
+        return rc;
+    }
+
+    delete[] buf;
+    return 0;
+}
+
+int main(int argc, char* argv[]) {
+    mbed_trace_init();
+
+    printf("HelloTSLSocket, HTTPS example of TLSSocket\n");
+    printf("\n");
+
+    // Open a network interface
+    NetworkInterface* network = NetworkInterface::get_default_instance();
+
+    if (network->connect()) {
+        printf("Unable to connect to network\n");
+        return -1;
+    }
+
+    printf("Connected to network!\n");
+
+
+    // Create transport socket
+    TCPSocket tcp;
+    nsapi_error_t err = tcp.open(network);
+    MBED_ASSERT(err == NSAPI_ERROR_OK);
+
+    // Resolve target name
+    SocketAddress addr;
+    err = network->gethostbyname(HOST_NAME, &addr);
+    MBED_ASSERT(err == NSAPI_ERROR_OK);
+    addr.set_port(PORT);
+
+    // Connect the trasport
+    printf("Connecting to %s\n", HOST_NAME);
+
+    err = tcp.connect(addr);
+    MBED_ASSERT(err == NSAPI_ERROR_OK);
+
+    // Create a TLS socket
+    TLSSocket tls(&tcp);
+
+    // Set root CA certificate
+    tls.set_root_ca_cert(cert);
+
+    // Start TLS handshake
+    printf("Start TLS handshake\n");
+    if(tls.start_handshake(HOST_NAME) != 0) {
+        printf("Failed to connect to the server.");
+        return -1;
+    }
+
+    err = http_get(&tls);
+    if (err == 0) {
+        printf("HTTP Download succesfull\n");
+    }
+
+    // Done
+    printf("HelloTSLSocket DONE.\n");
+
+    tcp.close();
+}
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLSSocket.cpp	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,57 @@
+/*
+ * PackageLicenseDeclared: Apache-2.0
+ * Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You 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.
+ */
+
+#include "TLSSocket.h"
+
+#define TRACE_GROUP "TLSS"
+#include "mbed-trace/mbed_trace.h"
+
+
+/*TLSSocket::SocketAddress getsock() {
+    return sock_addr;
+}*/
+
+
+nsapi_error_t TLSSocket::connect(const char *host, uint16_t port)
+{
+    printf("[.] Hello from TLSSocket::connect() \n");
+    int ret;
+    
+    sock_addr.set_ip_address(host);
+    sock_addr.set_port(port);
+    set_hostname(host);
+    
+    uint32_t init, final, TCPH, TTPH;
+    init = osKernelGetTickCount();
+    /* Send a 'Client Hello' buffer in order to start a thread on the server */ 
+    const char* buffer = "Client Hello";
+    if ((ret = udp_socket.sendto(host, port, (const char*) buffer, strlen(buffer))) <= 0)
+        printf("Couldn't send 'Client Hello' \n");
+    else
+        printf("sent 'Client Hello' \n"); 
+    wait(1);     
+    final = osKernelGetTickCount();
+    
+    TCPH = final - init;
+    TTPH = TCPH/osKernelGetTickFreq();
+    
+    printf("\nTCPH: %d\n", TCPH);
+    printf("\nTTPH: %d\n", TTPH); 
+    printf("\nTickFreq: %d\n", osKernelGetTickFreq()); 
+    
+    return TLSSocketWrapper::connect(sock_addr);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLSSocket.h	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,100 @@
+/*
+ * PackageLicenseDeclared: Apache-2.0
+ * Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You 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.
+ */
+
+#ifndef _MBED_HTTPS_TLS_TCP_SOCKET_H_
+#define _MBED_HTTPS_TLS_TCP_SOCKET_H_
+
+//#include "netsocket/TCPSocket.h"
+#include "netsocket/UDPSocket.h"
+#include "TLSSocketWrapper.h"
+
+//#include "mbedtls/platform.h"
+//#include "mbedtls/ssl.h"
+//#include "mbedtls/entropy.h"
+//#include "mbedtls/ctr_drbg.h"
+//#include "mbedtls/error.h"
+
+/**
+ * \brief TLSSocket a wrapper around TCPSocket for interacting with TLS servers
+ */
+class TLSSocket : public TLSSocketWrapper {
+public:
+
+    /** Create an uninitialized socket
+     *
+     *  Must call open to initialize the socket on a network stack.
+     */
+    TLSSocket() : TLSSocketWrapper(&udp_socket) {
+        
+        }
+
+    /** Create a socket on a network interface
+     *
+     *  Creates and opens a socket on the network stack of the given
+     *  network interface.
+     *
+     *  @param stack    Network stack as target for socket
+     */
+    template <typename S>
+    TLSSocket(S *stack, const char *hostname = NULL) : TLSSocketWrapper(&udp_socket, hostname)
+    {
+        nsapi_error_t ret;
+        if((ret = udp_socket.open(stack)) < 0)
+            printf("[.] UDP Socket Opening Failure\n");
+        else {
+            MBED_ASSERT(ret == NSAPI_ERROR_OK);
+            printf("[.] UDP Socket Opening Successful\n");
+        }
+    }
+
+    /** Opens a socket
+     *
+     *  Creates a network socket on the network stack of the given
+     *  network interface. Not needed if stack is passed to the
+     *  socket's constructor.
+     *
+     *  @param stack    Network stack as target for socket
+     *  @return         0 on success, negative error code on failure
+     */
+    virtual nsapi_error_t open(NetworkStack *stack) {
+        return udp_socket.open(stack);
+    }
+
+    template <typename S>
+    nsapi_error_t open(S *stack) {
+        return open(nsapi_create_stack(stack));
+    }
+
+    using TLSSocketWrapper::connect;
+
+    /** Connects TCP socket to a remote host
+     *
+     *  Initiates a connection to a remote server specified by either
+     *  a domain name or an IP address and a port.
+     *
+     *  @param host     Hostname of the remote host
+     *  @param port     Port of the remote host
+     *  @return         0 on success, negative error code on failure
+     */
+    nsapi_error_t connect(const char *host, uint16_t port);
+    //SocketAddress getsock();
+    SocketAddress sock_addr;
+private:
+    UDPSocket udp_socket;
+};
+
+#endif // _MBED_HTTPS_TLS_TCP_SOCKET_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLSSocketWrapper.cpp	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,633 @@
+/*
+ * PackageLicenseDeclared: Apache-2.0
+ * Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You 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.
+ */
+
+#include "TLSSocketWrapper.h"
+#include "drivers/Timer.h"
+
+#define TRACE_GROUP "TLSW"
+#include "mbed-trace/mbed_trace.h"
+#include "mbed_mem_trace.h"
+#include "mbedtls/debug.h"
+//#include "mbedtls/config.h"
+//#include "mbedtls/timing.h"
+//#include "timing_alt.h"
+
+TLSSocketWrapper::TLSSocketWrapper(Socket *transport, const char *hostname) :
+    _client_auth(false),
+    _keep_transport_open(false),
+    _handshake_completed(false),
+    _transport(transport)
+{
+    tls_init();
+    if (hostname) {
+        set_hostname(hostname);
+    }
+}
+
+TLSSocketWrapper::~TLSSocketWrapper() {
+    if (_transport) {
+        close();
+    }
+}
+
+void TLSSocketWrapper::set_hostname(const char *hostname)
+{
+    if (is_tls_allocated()) {
+        printf("ssl hostname is set\n");
+        mbedtls_ssl_set_hostname(_ssl, hostname);
+    }
+}
+
+void TLSSocketWrapper::keep_transport_open()
+{
+    _keep_transport_open = true;
+}
+
+nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const void *root_ca, size_t len)
+{
+    if (!is_tls_allocated()) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    /* Parse CA certification */
+    int ret;
+    if ((ret = mbedtls_x509_crt_parse(_cacert, static_cast<const unsigned char *>(root_ca),
+                        len)) != 0) {
+        print_mbedtls_error("mbedtls_x509_crt_parse", ret);
+        return NSAPI_ERROR_PARAMETER;
+    }
+        printf("Root CA Certificate Setting ... OK\n");                                     
+    return NSAPI_ERROR_OK;
+
+}
+nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const char *root_ca_pem)
+{
+    return set_root_ca_cert(root_ca_pem, strlen(root_ca_pem) + 1);
+}
+
+nsapi_error_t TLSSocketWrapper::set_client_cert_key(const char *client_cert_pem, const char *client_private_key_pem)
+{
+    return set_client_cert_key(client_cert_pem, strlen(client_cert_pem) + 1, client_private_key_pem, strlen(client_private_key_pem) + 1);
+}
+
+nsapi_error_t TLSSocketWrapper::set_client_cert_key(const void *client_cert, size_t client_cert_len,
+        const void *client_private_key_pem, size_t client_private_key_len)
+{
+    if (!is_tls_allocated()) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    int ret;
+    
+    if((NULL != client_cert) && (NULL != client_private_key_pem)) {
+        mbedtls_x509_crt_init(_clicert);
+        if((ret = mbedtls_x509_crt_parse(_clicert, static_cast<const unsigned char *>(client_cert),
+                client_cert_len)) != 0) {
+            print_mbedtls_error("mbedtls_x509_crt_parse", ret);
+            return NSAPI_ERROR_PARAMETER;
+        }
+                printf("Client Certificate Setting ... ok\n");              
+        mbedtls_pk_init(_pkctx);
+        if((ret = mbedtls_pk_parse_key(_pkctx, static_cast<const unsigned char *>(client_private_key_pem),
+                client_private_key_len, NULL, 0)) != 0) {
+            print_mbedtls_error("mbedtls_pk_parse_key", ret);
+            return NSAPI_ERROR_PARAMETER;
+        }
+                printf("Client pvt. Key Setting ... ok\n");                 
+        _client_auth = true;
+    }
+    return NSAPI_ERROR_OK;
+}
+
+int TLSSocketWrapper::set_client_kpsa_kpsaID_cipher(){ 
+    const unsigned char _kpsa[5] = { 0x05, 0x04, 0x03, 0x02, 0x01 }; 
+    // const unsigned char *_kpsa = "1a2b3c4d5e1a2b3c4d5e"; // 4 Bytes PSK
+    const unsigned char *_kpsaID = "AE456-LOCK@in.provider.com"; // 15 Bytes PSK-ID     
+     /* The supported CERT ciphersuites are as follows:     
+             CipherSuite TLS_RSA_WITH_AES_128_CCM       = {0xC0,0x9C}
+             CipherSuite TLS_RSA_WITH_AES_256_CCM       = {0xC0,0x9D)
+             CipherSuite TLS_DHE_RSA_WITH_AES_128_CCM   = {0xC0,0x9E}
+             CipherSuite TLS_DHE_RSA_WITH_AES_256_CCM   = {0xC0,0x9F}
+             CipherSuite TLS_RSA_WITH_AES_128_CCM_8     = {0xC0,0xA0}
+             CipherSuite TLS_RSA_WITH_AES_256_CCM_8     = {0xC0,0xA1)
+             CipherSuite TLS_DHE_RSA_WITH_AES_128_CCM_8 = {0xC0,0xA2}
+             CipherSuite TLS_DHE_RSA_WITH_AES_256_CCM_8 = {0xC0,0xA3}
+        // The supported PSK ciphersuites are as follows:
+             CipherSuite TLS_PSK_WITH_AES_128_CCM       = {0xC0,0xA4}
+             CipherSuite TLS_PSK_WITH_AES_256_CCM       = {0xC0,0xA5)
+             CipherSuite TLS_DHE_PSK_WITH_AES_128_CCM   = {0xC0,0xA6}
+             CipherSuite TLS_DHE_PSK_WITH_AES_256_CCM   = {0xC0,0xA7}
+             CipherSuite TLS_PSK_WITH_AES_128_CCM_8     = {0xC0,0xA8}
+             CipherSuite TLS_PSK_WITH_AES_256_CCM_8     = {0xC0,0xA9)
+             CipherSuite TLS_PSK_DHE_WITH_AES_128_CCM_8 = {0xC0,0xAA}
+             CipherSuite TLS_PSK_DHE_WITH_AES_256_CCM_8 = {0xC0,0xAB} 
+        // The supported PSK Cipher is (TLS)
+             TLS_PSK_WITH_RC4_128_SHA          = { 0x00, 0x8A };
+             TLS_PSK_WITH_3DES_EDE_CBC_SHA     = { 0x00, 0x8B };
+             TLS_PSK_WITH_AES_128_CBC_SHA      = { 0x00, 0x8C };
+             TLS_PSK_WITH_AES_256_CBC_SHA      = { 0x00, 0x8D };    */ 
+    /*int cipher[10];
+    for(int i=0; i<4; i++) {  
+        cipher[i*2]=0;
+        cipher[i*2+1]=0x8A+i;  
+    }
+    cipher[8] = 0;
+    cipher[9] = 0; */
+    
+    /*mbedtls_ssl_conf_ciphersuites(_ssl_conf, cipher); 
+    printf("mbedtls_ssl_conf_ciphersuites() .. ok\n");
+
+    int cipher;
+    const int *cipherPTR;
+    cipher = MBEDTLS_SSL_CIPHERSUITES;
+    cipherPTR = &cipher;  */
+
+    int kpsa_len = strlen((const char*) _kpsa);
+    int kpsaID_len = strlen((const char*) _kpsaID);
+    int ret;
+    mbedtls_ssl_set_hs_psk(_ssl, _kpsa, kpsa_len);
+    if( (ret = mbedtls_ssl_conf_psk(_ssl_conf, _kpsa, kpsa_len , _kpsaID, kpsaID_len)) != 0){
+        print_mbedtls_error("mbedtls_psk_error", ret);
+        // return NSAPI_ERROR_PARAMETER;
+        return -1;
+    } 
+    printf("Ok.\n"); 
+    return 0; 
+}
+
+nsapi_error_t TLSSocketWrapper::do_handshake() {
+    nsapi_error_t _error;
+    const char DRBG_PERS[] = "mbed TLS client";
+   
+        const int *cipherArray;
+    cipherArray = mbedtls_ssl_list_ciphersuites();
+    printf("[+] The allowed ciphersuites are: \n");
+    int i = 0;
+    while (cipherArray[i] != 0) {
+        printf("[.] cipherArray[%d] = %d\n", i, cipherArray[i]);
+        i++;
+    } 
+    
+    if (!_transport) {
+        printf("[-] transport/socket not available\n");
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    if (!is_tls_allocated()) {
+        printf("[-] no tls allocated\n");
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    _transport->set_blocking(false);
+    /*
+     * Initialize TLS-related stuf.
+     */
+    int ret;
+    if ((ret = mbedtls_ctr_drbg_seed(_ctr_drbg, mbedtls_entropy_func, _entropy,
+                        (const unsigned char *) DRBG_PERS,
+                        sizeof (DRBG_PERS))) != 0) {
+        print_mbedtls_error("mbedtls_crt_drbg_init", ret);
+        _error = ret;
+        return _error;
+    }
+
+    printf("[+] Configuring a dtls-client session initiation ... ");
+    mbedtls_ssl_conf_endpoint(_ssl_conf, MBEDTLS_SSL_IS_CLIENT);
+    mbedtls_ssl_conf_transport(_ssl_conf, MBEDTLS_SSL_TRANSPORT_DATAGRAM);
+
+    tr_info("mbedtls_ssl_config_defaults()");
+    if ((ret = mbedtls_ssl_config_defaults(_ssl_conf,
+                    MBEDTLS_SSL_IS_CLIENT,
+                    MBEDTLS_SSL_TRANSPORT_DATAGRAM,
+                    MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
+        print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
+        _error = ret;
+        return _error;
+    } 
+    tr_info("mbedtls_ssl_conf_ca_chain()");
+    mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL);     
+    tr_info("mbedtls_ssl_conf_rng()");
+    mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg);
+    printf("ok\n");
+    
+    /* It is possible to disable authentication by passing
+      MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
+     */
+    printf("[+] Configuring the Session Information ... ");
+    tr_info("mbedtls_ssl_conf_authmode()");
+    mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE);
+    
+    mbedtls_ssl_conf_verify(_ssl_conf, my_verify, NULL);
+    mbedtls_ssl_conf_dbg(_ssl_conf, my_debug, NULL);
+    mbedtls_debug_set_threshold(3);
+
+    /*  configure the timers for retransmission of lost handshake messages
+            1,000 milli-sec minimum time to 6,000 milli-sec maximum delay   */  
+        mbedtls_ssl_conf_handshake_timeout(_ssl_conf, 1000, 6000);
+    
+    /* Anti-Replay Protection */
+        mbedtls_ssl_conf_dtls_anti_replay(_ssl_conf, MBEDTLS_SSL_ANTI_REPLAY_ENABLED);
+
+    /* Bad Mac Limit for 10 Packets */
+        mbedtls_ssl_conf_dtls_badmac_limit(_ssl_conf, 10);
+
+    /* Set the limit for the Maximum Transmission Unit for DTLS Payload 
+         {1500 Bits Set} */
+        mbedtls_ssl_set_mtu( _ssl , 1500 );
+
+    tr_info("mbedtls_ssl_setup()");
+    if ((ret = mbedtls_ssl_setup(_ssl, _ssl_conf)) != 0) {
+        print_mbedtls_error("mbedtls_ssl_setup", ret);
+        _error = ret;
+        return _error;
+    }
+    printf("ok\n");
+    
+    printf("[+] Configuring the Bio ... ");
+    mbedtls_ssl_set_bio(_ssl, this, ssl_send, ssl_recv, NULL );
+    printf("ok\n");
+    
+    if(_client_auth) {
+                printf("[+] Configuring Client's pvtKey & certKey ... "); 
+        if((ret = mbedtls_ssl_conf_own_cert(_ssl_conf, _clicert, _pkctx)) != 0) {
+            print_mbedtls_error("mbedtls_ssl_conf_own_cert", ret);
+            _error = ret;
+            return _error;
+        }
+                printf("ok\n");
+    } 
+    
+    printf("[+] Timing Call-Back Setting ... "); 
+    mbedtls_ssl_set_timer_cb(_ssl, _ssl_timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay);
+    printf("ok\n");
+
+    /* Start the handshake, the rest will be done in onReceive() */ 
+    //uint32_t init, final, TCPH, TTPH;
+    printf("[+] DTLS Handshake Connecting \n");    
+    //init = osKernelGetTickCount(); 
+    if ((ret = mbedtls_ssl_handshake(_ssl)) != 0) {
+        printf("[-] mbedtls_ssl_handshake error %d\n", ret);
+        return ret;
+    } 
+    else {
+        //final = osKernelGetTickCount();
+        printf("[+] DTLS Hanshake Connected \n");
+    } 
+    
+    //TCPH = final - init;
+    //TTPH = TCPH/osKernelGetTickFreq();
+    
+    //printf("\nTCPH: %d\n", TCPH);
+    //printf("\nTTPH: %d\n", TTPH); 
+    //printf("\nTickFreq: %d\n", osKernelGetTickFreq()); 
+    
+    /* It also means the handshake is done, time to print info */
+    tr_info("[+] TLS connection to %s established\r\n", _ssl->hostname);
+    // Prints the server certificate and verify it. 
+    
+    const size_t buf_size = 1024;
+    char* buf = new char[buf_size];
+    mbedtls_x509_crt_info(buf, buf_size, "\r    ",  mbedtls_ssl_get_peer_cert(_ssl));
+    tr_debug("[+] Server certificate:\r\n%s\r\n", buf);
+
+    uint32_t flags = mbedtls_ssl_get_verify_result(_ssl);
+    if( flags != 0 ) { 
+    //  Verification failed.   
+        mbedtls_x509_crt_verify_info(buf, buf_size, "\r  ! ", flags); 
+        tr_error("[+] Certificate verification failed:\r\n%s", buf);
+    } else { 
+        // Verification succeeded.   
+        tr_info("[+] Certificate verification passed"); 
+    }  
+    delete[] buf; 
+    _handshake_completed = true;
+
+    return 0;
+}
+
+nsapi_error_t TLSSocketWrapper::send(const void *data, nsapi_size_t size) {
+    int ret;
+
+    if (!is_tls_allocated()) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    tr_debug("send %d", size);
+    //uint32_t init, final, TCPH, TTPH;
+    //init = osKernelGetTickCount();
+    ret = mbedtls_ssl_write(_ssl, (const unsigned char *) data, size);
+    //final = osKernelGetTickCount();
+        
+    /*TCPH = final - init;
+    TTPH = TCPH/osKernelGetTickFreq();
+    
+    printf("\nTCPH: %d\n", TCPH);
+    printf("\nTTPH: %d\n", TTPH); 
+    printf("\nTickFreq: %d\n", osKernelGetTickFreq()); */
+
+    if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
+        ret == MBEDTLS_ERR_SSL_WANT_READ) {
+        // translate to socket error
+        return NSAPI_ERROR_WOULD_BLOCK;
+    }
+    if (ret < 0) {
+        print_mbedtls_error("mbedtls_ssl_write", ret);
+    }
+    return ret; // Assume "non negative errorcode" to be propagated from Socket layer
+}
+
+nsapi_size_or_error_t TLSSocketWrapper::sendto(const SocketAddress &, const void *data, nsapi_size_t size)
+{
+    // Ignore the SocketAddress
+    return send(data, size);
+}
+
+nsapi_size_or_error_t TLSSocketWrapper::recv(void *data, nsapi_size_t size) {
+    int ret;
+
+    if (!is_tls_allocated()) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    
+    ret = mbedtls_ssl_read(_ssl, (unsigned char *) data, size);
+    
+    if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
+        ret == MBEDTLS_ERR_SSL_WANT_READ) {
+        // translate to socket error
+        return NSAPI_ERROR_WOULD_BLOCK;
+    } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+        /* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is not considered as error.
+         * Just ignre here. Once connection is closed, mbedtls_ssl_read()
+         * will return 0.
+         */
+        return 0;
+    } else if (ret < 0) {
+        print_mbedtls_error("mbedtls_ssl_read", ret);
+        // TODO: Should I translate SSL errors to some socket error?
+    }
+    return ret;
+}
+
+nsapi_size_or_error_t TLSSocketWrapper::recvfrom(SocketAddress *address, void *data, nsapi_size_t size)
+{
+    //TODO: Need Socket::getpeername() to get address
+    return recv(data, size);
+}
+
+void TLSSocketWrapper::print_mbedtls_error(const char *name, int err) {
+    char *buf = new char[128];
+    mbedtls_strerror(err, buf, 128);
+    tr_err("%s() failed: -0x%04x (%d): %s", name, -err, err, buf);
+    delete[] buf;
+}
+
+
+#if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
+
+void TLSSocketWrapper::my_debug(void *ctx, int level, const char *file, int line,
+                        const char *str)
+{
+    const char *p, *basename;
+    (void) ctx;
+
+    /* Extract basename from file */
+    for(p = basename = file; *p != '\0'; p++) {
+        if(*p == '/' || *p == '\\') {
+            basename = p + 1;
+        }
+    }
+
+    tr_debug("%s:%04d: |%d| %s", basename, line, level, str);
+}
+
+int TLSSocketWrapper::my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
+{
+    const uint32_t buf_size = 1024;
+    char *buf = new char[buf_size];
+    (void) data;
+
+    tr_debug("\nVerifying certificate at depth %d:\n", depth);
+    mbedtls_x509_crt_info(buf, buf_size - 1, "  ", crt);
+    tr_debug("%s", buf);
+
+    if (*flags == 0)
+        tr_info("No verification issue for this certificate\n");
+    else
+    {
+        mbedtls_x509_crt_verify_info(buf, buf_size, "  ! ", *flags);
+        tr_info("%s\n", buf);
+    }
+
+    delete[] buf;
+
+    return 0;
+}
+#endif /* MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 */
+
+
+int TLSSocketWrapper::ssl_recv(void *ctx, unsigned char *buf, size_t len) {
+    int recv;
+
+    TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
+
+    if (!my->_transport) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    recv = my->_transport->recv(buf, len);
+
+    if (NSAPI_ERROR_WOULD_BLOCK == recv) {
+        return MBEDTLS_ERR_SSL_WANT_READ;
+    } else if(recv < 0) {
+        tr_error("Socket recv error %d", recv);
+    }
+    // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
+    return recv;
+}
+
+int TLSSocketWrapper::ssl_send(void *ctx, const unsigned char *buf, size_t len) {
+    int size = -1;
+    TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx);
+
+    if (!my->_transport) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    size = my->_transport->send(buf, len);
+
+    if (NSAPI_ERROR_WOULD_BLOCK == size) {
+        return MBEDTLS_ERR_SSL_WANT_WRITE;
+    } else if(size < 0){
+        tr_error("Socket send error %d", size);
+    }
+    // Propagate also Socket errors to SSL, it allows negative error codes to be returned here.
+    return size;
+ }
+
+void TLSSocketWrapper::tls_init() {
+    _entropy = new mbedtls_entropy_context;
+    _ctr_drbg = new mbedtls_ctr_drbg_context;
+    _cacert = new mbedtls_x509_crt;
+    _clicert = new mbedtls_x509_crt;
+    _pkctx = new mbedtls_pk_context;
+    _ssl = new mbedtls_ssl_context;
+    _ssl_conf = new mbedtls_ssl_config;
+    _ssl_timer = new mbedtls_timing_delay_context;
+    
+    mbedtls_entropy_init(_entropy);
+    mbedtls_ctr_drbg_init(_ctr_drbg);
+    mbedtls_x509_crt_init(_cacert);
+    mbedtls_x509_crt_init(_clicert);
+    mbedtls_pk_init(_pkctx);
+    mbedtls_ssl_init(_ssl);
+    mbedtls_ssl_config_init(_ssl_conf);    
+}
+
+void TLSSocketWrapper::tls_free() {
+    mbedtls_entropy_free(_entropy);
+    mbedtls_ctr_drbg_free(_ctr_drbg);
+    mbedtls_x509_crt_free(_cacert);
+    mbedtls_x509_crt_free(_clicert);
+    mbedtls_pk_free(_pkctx);
+    mbedtls_ssl_free(_ssl);
+    mbedtls_ssl_config_free(_ssl_conf);
+
+    delete _entropy;
+    delete _ctr_drbg;
+    delete _cacert;
+    delete _clicert;
+    delete _pkctx;
+    delete _ssl;
+    delete _ssl_conf;
+    delete _ssl_timer;
+    _ssl = NULL; // Marks that TLS context is freed
+}
+
+bool TLSSocketWrapper::is_tls_allocated() {
+    return _ssl != NULL;
+}
+
+nsapi_error_t TLSSocketWrapper::close()
+{
+    if (!_transport) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    if (!is_tls_allocated()) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    tr_info("Closing TLS");
+
+    int ret = 0;
+    if (_handshake_completed) {
+        _transport->set_blocking(true);
+        ret = mbedtls_ssl_close_notify(_ssl);
+        if (ret) {
+            print_mbedtls_error("mbedtls_ssl_close_notify", ret);
+        }
+        _handshake_completed = false;
+    }
+
+    if (!_keep_transport_open) {
+        int ret2 = _transport->close();
+        if (!ret) {
+            ret = ret2;
+        }
+    }
+
+    _transport = NULL;
+
+    tls_free();
+
+    return ret;
+}
+
+nsapi_error_t TLSSocketWrapper::connect(const SocketAddress &address)
+{
+    printf("Hello from TLSSocketWrapper::connect().\n");
+    if (!_transport) {
+        printf("transport not available\n");
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    //TODO: We could initiate the hanshake here, if there would be separate function call to set the target hostname
+    nsapi_error_t ret = _transport->connect(address);
+    if (ret) {
+        printf("transport->connect() failed, %d\n", ret);
+        printf("error return from TLSSocketWrapper::connect %d\n", ret);
+        return ret;
+    } 
+    return do_handshake();
+}
+
+nsapi_error_t TLSSocketWrapper::bind(const SocketAddress &address)
+{
+    if (!_transport) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    return _transport->bind(address);
+}
+
+void TLSSocketWrapper::set_blocking(bool blocking)
+{
+    if (!_transport) {
+        return;
+    }
+    _transport->set_blocking(blocking);
+}
+
+void TLSSocketWrapper::set_timeout(int timeout)
+{
+    if (!_transport) {
+        return;
+    }
+    _transport->set_timeout(timeout);
+}
+
+void TLSSocketWrapper::sigio(mbed::Callback<void()> func)
+{
+    if (!_transport) {
+        return;
+    }
+    // Allow sigio() to propagate to upper level and handle errors on recv() and send()
+    _transport->sigio(func);
+}
+
+nsapi_error_t TLSSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
+{
+    if (!_transport) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    return _transport->setsockopt(level, optname, optval, optlen);
+}
+
+nsapi_error_t TLSSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen)
+{
+    if (!_transport) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+    return _transport->getsockopt(level, optname, optval, optlen);
+}
+
+Socket *TLSSocketWrapper::accept(nsapi_error_t *err)
+{
+    if (err) {
+        *err = NSAPI_ERROR_UNSUPPORTED;
+    }
+    return NULL;
+}
+
+nsapi_error_t TLSSocketWrapper::listen(int)
+{
+    return NSAPI_ERROR_UNSUPPORTED;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLSSocketWrapper.h	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,194 @@
+/*
+ * PackageLicenseDeclared: Apache-2.0
+ * Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You 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.
+ */
+
+#ifndef _MBED_HTTPS_TLS_SOCKET_WRAPPER_H_
+#define _MBED_HTTPS_TLS_SOCKET_WRAPPER_H_
+
+#include "mbed.h"
+#include "netsocket/Socket.h"
+#include "mbedtls/platform.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+#include "mbedtls/timing.h"
+#include <Timer.h>
+
+//#include "timing_alt.h"
+/**
+ * \brief TLSSocket a wrapper around Socket for interacting with TLS servers
+ */
+class TLSSocketWrapper : public Socket {
+public:
+    /* Create a TLSSocketWrapper
+     *
+     * @param transport    Underlying transport socket to wrap
+     * @param hostname     Hostname of the remote host, used for certificate checking
+     */
+    TLSSocketWrapper(Socket *transport, const char *hostname = NULL);
+
+    /** Destroy a socket wrapper
+     *
+     *  Closes socket wrapper if the socket wrapper is still open
+     */
+    virtual ~TLSSocketWrapper();
+
+    /** Specify that transport does not get closed
+     *
+     *  By default, closing or destroying the socket wrapper will close the
+     *  transport socket.
+     *  Calling this will make the wrapper leave the transport socket open.
+     */
+    void keep_transport_open();
+
+    void set_hostname(const char *hostname);
+
+    /** Sets the certification of Root CA.
+     *
+     * @param root_ca Root CA Certificate in any mbed-TLS supported format.
+     * @param len     Length of certificate (including terminating 0 for PEM).
+     */
+    nsapi_error_t set_root_ca_cert(const void *root_ca, size_t len);
+
+    /** Sets the certification of Root CA.
+     *
+     * @param root_ca_pem Root CA Certificate in PEM format
+     */
+    nsapi_error_t set_root_ca_cert(const char *root_ca_pem);
+
+    /** Sets client certificate, and client private key.
+     *
+     * @param client_cert Client certification in any mbed-TLS supported format.
+     * @param client_private_key Client private key in PEM format.
+     */
+    nsapi_error_t set_client_cert_key(const void *client_cert_pem, size_t client_cert_len,
+                                      const void *client_private_key_pem, size_t client_private_key_len);
+
+    /** Sets client certificate, and client private key.
+     *
+     * @param client_cert_pem Client certification in PEM format.
+     * @param client_private_key Client private key in PEM format.
+     */
+    nsapi_error_t set_client_cert_key(const char *client_cert_pem, const char *client_private_key_pem);
+    
+    int set_client_kpsa_kpsaID_cipher();
+    /** Initiates TLS Handshake
+     *
+     *  Initiates a TLS hanshake to a remote speer
+     *  Underlying transport socket should already be connected
+     *
+     *  Root CA certification must be set by set_ssl_ca_pem() before
+     *  call this function.
+     *
+     *  @return         0 on success, negative error code on failure
+     */
+    nsapi_error_t do_handshake();
+
+    /** Send data over a TLS socket
+     *
+     *  The socket must be connected to a remote host. Returns the number of
+     *  bytes sent from the buffer.
+     *
+     *  @param data     Buffer of data to send to the host
+     *  @param size     Size of the buffer in bytes
+     *  @return         Number of sent bytes on success, negative error
+     *                  code on failure
+     */
+    virtual nsapi_error_t send(const void *data, nsapi_size_t size);
+
+    /** Receive data over a TLS socket
+     *
+     *  The socket must be connected to a remote host. Returns the number of
+     *  bytes received into the buffer.
+     *
+     *  @param data     Destination buffer for data received from the host
+     *  @param size     Size of the buffer in bytes
+     *  @return         Number of received bytes on success, negative error
+     *                  code on failure. If no data is available to be received
+     *                  and the peer has performed an orderly shutdown,
+     *                  recv() returns 0.
+     */
+    virtual nsapi_size_or_error_t recv(void *data, nsapi_size_t size);
+
+     virtual nsapi_error_t close();
+     virtual nsapi_error_t connect(const SocketAddress &address);
+     virtual nsapi_size_or_error_t sendto(const SocketAddress &address, const void *data, nsapi_size_t size);
+     virtual nsapi_size_or_error_t recvfrom(SocketAddress *address,
+            void *data, nsapi_size_t size);
+     virtual nsapi_error_t bind(const SocketAddress &address);
+     virtual void set_blocking(bool blocking);
+     virtual void set_timeout(int timeout);
+     virtual void sigio(mbed::Callback<void()> func);
+     virtual nsapi_error_t setsockopt(int level, int optname, const void *optval, unsigned optlen);
+     virtual nsapi_error_t getsockopt(int level, int optname, void *optval, unsigned *optlen);
+     virtual Socket *accept(nsapi_error_t *error = NULL);
+     virtual nsapi_error_t listen(int backlog = 1);
+
+protected:
+    /**
+     * Helper for pretty-printing mbed TLS error codes
+     */
+    static void print_mbedtls_error(const char *name, int err);
+
+//#if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
+    /**
+     * Debug callback for mbed TLS
+     * Just prints on the USB serial port
+     */
+    static void my_debug(void *ctx, int level, const char *file, int line,
+                        const char *str);
+    /**
+     * Certificate verification callback for mbed TLS
+     * Here we only use it to display information on each cert in the chain
+     */
+    static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags);
+//#endif /* MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 */
+
+    /**
+     * Receive callback for Mbed TLS
+     */
+    static int ssl_recv(void *ctx, unsigned char *buf, size_t len);
+
+    /**
+     * Send callback for Mbed TLS
+     */
+    static int ssl_send(void *ctx, const unsigned char *buf, size_t len);
+
+private:
+    bool _client_auth;
+    bool _keep_transport_open;
+    bool _handshake_completed;
+    Socket *_transport;
+
+    mbedtls_entropy_context* _entropy;
+    mbedtls_ctr_drbg_context* _ctr_drbg;
+    mbedtls_x509_crt* _cacert;
+    mbedtls_x509_crt* _clicert;
+    mbedtls_pk_context* _pkctx;
+    mbedtls_ssl_context* _ssl;
+    mbedtls_ssl_config* _ssl_conf;
+    struct mbedtls_timing_delay_context *_ssl_timer;
+
+    /* Allocates required memory */
+    void tls_init(void);
+    /* Frees memory */
+    void tls_free(void);
+    /* Returns true if TLS context is allocated, false if freed */
+    bool is_tls_allocated();
+};
+
+#endif // _MBED_HTTPS_TLS_SOCKET_WRAPPER_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_lib.json	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,9 @@
+{
+    "name": "tls-socket",
+    "macros": [
+        "MBEDTLS_SHA1_C"
+    ],
+    "config": {
+        "debug-level":              1
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/timing_alt.h	Fri Aug 23 13:29:35 2019 +0000
@@ -0,0 +1,224 @@
+/**
+ * \file timing.h
+ *
+ * \brief Portable interface to timeouts and to the CPU cycle counter
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You 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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+//#ifndef MBEDTLS_TIMING_H
+//#define MBEDTLS_TIMING_H
+
+//#if !defined(MBEDTLS_CONFIG_FILE)
+//#include "config.h"
+//#else
+//#include MBEDTLS_CONFIG_FILE
+//#endif
+
+#include <stdint.h>
+
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+
+// Regular implementation
+//
+
+/**
+ * \brief          timer structure
+ */
+/*struct mbedtls_timing_hr_time
+{
+    unsigned char opaque[32];
+}; */ 
+
+#include "mbed.h"
+//#include <Timer.h>
+
+//Timer       *timer;
+//uint32_t    start, now;
+/**
+ * \brief          Context for mbedtls_timing_set/get_delay()
+ */
+//timer->start();
+/*
+struct dtls_timer_context {
+    Timer       *timer; 
+    uint32_t    int_ms;
+    uint32_t    fin_ms;
+    uint32_t    now, start;
+}; */
+
+//Timer    timer;
+
+typedef struct mbedtls_timing_delay_context
+{
+    uint32_t                                                    now, ref;
+    //mbedtls_timing_hr_time            _hr_time;
+    uint32_t                            int_ms;
+    uint32_t                            fin_ms;
+};
+
+
+//extern volatile int mbedtls_timing_alarmed;
+
+/**
+ * \brief          Return the CPU cycle counter value
+ *
+ * \warning        This is only a best effort! Do not rely on this!
+ *                 In particular, it is known to be unreliable on virtual
+ *                 machines.
+ *
+ * \note           This value starts at an unspecified origin and
+ *                 may wrap around.
+ */
+//unsigned long mbedtls_timing_hardclock( void ){
+    
+//};
+
+/**
+ * \brief          Return the elapsed time in milliseconds
+ *
+ * \param val      points to a timer structure
+ * \param reset    If 0, query the elapsed time. Otherwise (re)start the timer.
+ *
+ * \return         Elapsed time since the previous reset in ms. When
+ *                 restarting, this is always 0.
+ *
+ * \note           To initialize a timer, call this function with reset=1.
+ *
+ *                 Determining the elapsed time and resetting the timer is not
+ *                 atomic on all platforms, so after the sequence
+ *                 `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
+ *                 get_timer(0) }` the value time1+time2 is only approximately
+ *                 the delay since the first reset.
+ */
+/*unsigned long mbedtls_timing_get_timer( mbedtls_timing_hr_time *val, int reset ){
+    if (reset) {
+        
+    }
+    else {
+        
+    }  
+}; */
+
+/**
+ * \brief          Setup an alarm clock
+ *
+ * \param seconds  delay before the "mbedtls_timing_alarmed" flag is set
+ *                 (must be >=0)
+ *
+ * \warning        Only one alarm at a time  is supported. In a threaded
+ *                 context, this means one for the whole process, not one per
+ *                 thread.
+ */
+//void mbedtls_set_alarm( int seconds );
+
+/**
+ * \brief          Set a pair of delays to watch
+ *                 (See \c mbedtls_timing_get_delay().)
+ *
+ * \param data     Pointer to timing data.
+ *                 Must point to a valid \c mbedtls_timing_delay_context struct.
+ * \param int_ms   First (intermediate) delay in milliseconds.
+ *                 The effect if int_ms > fin_ms is unspecified.
+ * \param fin_ms   Second (final) delay in milliseconds.
+ *                 Pass 0 to cancel the current delay.
+ *
+ * \note           To set a single delay, either use \c mbedtls_timing_set_timer
+ *                 directly or use this function with int_ms == fin_ms.
+ */
+// set delays to watch 
+void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ){
+
+        mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
+        //dtls_timer_context *ctx = (dtls_timer_context *) data;
+  
+        ctx->int_ms = int_ms;
+    ctx->fin_ms = fin_ms;
+    
+    printf("\nInitial delay time (ms) set: ctx->int_ms = %d\n", ctx->int_ms);
+    printf("\nFinish delay time (ms) set: ctx->fin_ms = %d\n", ctx->fin_ms);
+    
+    //timer.start();
+    //printf("\ntimer.start() executed and timer.read_ms() = %d\n", timer.read_ms());
+    
+    if( fin_ms != 0 ) {
+        // reset = 1; get_timer(data, 1)
+        // ref/start = put clocks
+        ctx->ref = osKernelGetTickCount();
+        printf("\nReference time set: ctx->ref = %d\n", ctx->ref);   
+    }
+};
+
+/**
+ * \brief          Get the status of delays
+ *                 (Memory helper: number of delays passed.)
+ *
+ * \param data     Pointer to timing data
+ *                 Must point to a valid \c mbedtls_timing_delay_context struct.
+ *
+ * \return         -1 if cancelled (fin_ms = 0),
+ *                  0 if none of the delays are passed,
+ *                  1 if only the intermediate delay is passed,
+ *                  2 if the final delay is passed.
+ */
+int mbedtls_timing_get_delay( void *data ){
+    
+        mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
+    //dtls_timer_context *ctx = (dtls_timer_context *) data;
+    
+        unsigned long elapsed_ms;
+
+    if( ctx->fin_ms == 0 ) {
+        printf("\n Timer has been reset, returned -1\n");
+        return( -1 );
+    }
+
+    ctx->now = osKernelGetTickCount();
+        elapsed_ms = ((ctx->now - ctx->ref) / osKernelGetTickFreq()) * 1000;
+    printf("\nThe elapsed delay time (ms) is: elapsed_ms = %d %d\n", elapsed_ms, osKernelGetTickFreq());
+
+    if( elapsed_ms >= ctx->fin_ms ) {
+        printf("\nFlight delay-Time has been over-delayed, returned 2\n");
+        return( 2 );
+    }
+
+    if( elapsed_ms >= ctx->int_ms ) {
+        printf("\nOnly the intermediate delay is passed, returned 1\n");
+        return( 1 );
+    }
+    
+    printf("\nNo delay is been passed, returned 0\n");
+    return( 0 );
+}; 
+
+//#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+//int mbedtls_timing_self_test( int verbose );
+//#endif
+
+//#ifdef __cplusplus
+//}
+//#endif
+
+//#endif /* timing.h */