..
TLSSocketWrapper.h@1:a6995e66c9f7, 2019-08-29 (annotated)
- Committer:
- ImranBilalButt
- Date:
- Thu Aug 29 06:43:11 2019 +0000
- Revision:
- 1:a6995e66c9f7
- Parent:
- 0:5f745af3ec9b
..;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ImranBilalButt | 0:5f745af3ec9b | 1 | /* |
ImranBilalButt | 0:5f745af3ec9b | 2 | * PackageLicenseDeclared: Apache-2.0 |
ImranBilalButt | 0:5f745af3ec9b | 3 | * Copyright (c) 2017 ARM Limited |
ImranBilalButt | 0:5f745af3ec9b | 4 | * |
ImranBilalButt | 0:5f745af3ec9b | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
ImranBilalButt | 0:5f745af3ec9b | 6 | * you may not use this file except in compliance with the License. |
ImranBilalButt | 0:5f745af3ec9b | 7 | * You may obtain a copy of the License at |
ImranBilalButt | 0:5f745af3ec9b | 8 | * |
ImranBilalButt | 0:5f745af3ec9b | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
ImranBilalButt | 0:5f745af3ec9b | 10 | * |
ImranBilalButt | 0:5f745af3ec9b | 11 | * Unless required by applicable law or agreed to in writing, software |
ImranBilalButt | 0:5f745af3ec9b | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
ImranBilalButt | 0:5f745af3ec9b | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ImranBilalButt | 0:5f745af3ec9b | 14 | * See the License for the specific language governing permissions and |
ImranBilalButt | 0:5f745af3ec9b | 15 | * limitations under the License. |
ImranBilalButt | 0:5f745af3ec9b | 16 | */ |
ImranBilalButt | 0:5f745af3ec9b | 17 | |
ImranBilalButt | 0:5f745af3ec9b | 18 | #ifndef _MBED_HTTPS_TLS_SOCKET_WRAPPER_H_ |
ImranBilalButt | 0:5f745af3ec9b | 19 | #define _MBED_HTTPS_TLS_SOCKET_WRAPPER_H_ |
ImranBilalButt | 0:5f745af3ec9b | 20 | |
ImranBilalButt | 0:5f745af3ec9b | 21 | #include "mbed.h" |
ImranBilalButt | 0:5f745af3ec9b | 22 | #include "netsocket/Socket.h" |
ImranBilalButt | 0:5f745af3ec9b | 23 | #include "mbedtls/platform.h" |
ImranBilalButt | 0:5f745af3ec9b | 24 | #include "mbedtls/ssl.h" |
ImranBilalButt | 0:5f745af3ec9b | 25 | #include "mbedtls/entropy.h" |
ImranBilalButt | 0:5f745af3ec9b | 26 | #include "mbedtls/ctr_drbg.h" |
ImranBilalButt | 0:5f745af3ec9b | 27 | #include "mbedtls/error.h" |
ImranBilalButt | 0:5f745af3ec9b | 28 | #include "mbedtls/timing.h" |
ImranBilalButt | 0:5f745af3ec9b | 29 | #include <Timer.h> |
ImranBilalButt | 0:5f745af3ec9b | 30 | |
ImranBilalButt | 1:a6995e66c9f7 | 31 | static RawSerial pc(USBTX, USBRX); // tx, rx |
ImranBilalButt | 1:a6995e66c9f7 | 32 | |
ImranBilalButt | 0:5f745af3ec9b | 33 | //#include "timing_alt.h" |
ImranBilalButt | 0:5f745af3ec9b | 34 | /** |
ImranBilalButt | 0:5f745af3ec9b | 35 | * \brief TLSSocket a wrapper around Socket for interacting with TLS servers |
ImranBilalButt | 0:5f745af3ec9b | 36 | */ |
ImranBilalButt | 0:5f745af3ec9b | 37 | class TLSSocketWrapper : public Socket { |
ImranBilalButt | 0:5f745af3ec9b | 38 | public: |
ImranBilalButt | 0:5f745af3ec9b | 39 | /* Create a TLSSocketWrapper |
ImranBilalButt | 0:5f745af3ec9b | 40 | * |
ImranBilalButt | 0:5f745af3ec9b | 41 | * @param transport Underlying transport socket to wrap |
ImranBilalButt | 0:5f745af3ec9b | 42 | * @param hostname Hostname of the remote host, used for certificate checking |
ImranBilalButt | 0:5f745af3ec9b | 43 | */ |
ImranBilalButt | 0:5f745af3ec9b | 44 | TLSSocketWrapper(Socket *transport, const char *hostname = NULL); |
ImranBilalButt | 0:5f745af3ec9b | 45 | |
ImranBilalButt | 0:5f745af3ec9b | 46 | /** Destroy a socket wrapper |
ImranBilalButt | 0:5f745af3ec9b | 47 | * |
ImranBilalButt | 0:5f745af3ec9b | 48 | * Closes socket wrapper if the socket wrapper is still open |
ImranBilalButt | 0:5f745af3ec9b | 49 | */ |
ImranBilalButt | 0:5f745af3ec9b | 50 | virtual ~TLSSocketWrapper(); |
ImranBilalButt | 0:5f745af3ec9b | 51 | |
ImranBilalButt | 0:5f745af3ec9b | 52 | /** Specify that transport does not get closed |
ImranBilalButt | 0:5f745af3ec9b | 53 | * |
ImranBilalButt | 0:5f745af3ec9b | 54 | * By default, closing or destroying the socket wrapper will close the |
ImranBilalButt | 0:5f745af3ec9b | 55 | * transport socket. |
ImranBilalButt | 0:5f745af3ec9b | 56 | * Calling this will make the wrapper leave the transport socket open. |
ImranBilalButt | 0:5f745af3ec9b | 57 | */ |
ImranBilalButt | 0:5f745af3ec9b | 58 | void keep_transport_open(); |
ImranBilalButt | 0:5f745af3ec9b | 59 | |
ImranBilalButt | 0:5f745af3ec9b | 60 | void set_hostname(const char *hostname); |
ImranBilalButt | 0:5f745af3ec9b | 61 | |
ImranBilalButt | 0:5f745af3ec9b | 62 | /** Sets the certification of Root CA. |
ImranBilalButt | 0:5f745af3ec9b | 63 | * |
ImranBilalButt | 0:5f745af3ec9b | 64 | * @param root_ca Root CA Certificate in any mbed-TLS supported format. |
ImranBilalButt | 0:5f745af3ec9b | 65 | * @param len Length of certificate (including terminating 0 for PEM). |
ImranBilalButt | 0:5f745af3ec9b | 66 | */ |
ImranBilalButt | 0:5f745af3ec9b | 67 | nsapi_error_t set_root_ca_cert(const void *root_ca, size_t len); |
ImranBilalButt | 0:5f745af3ec9b | 68 | |
ImranBilalButt | 0:5f745af3ec9b | 69 | /** Sets the certification of Root CA. |
ImranBilalButt | 0:5f745af3ec9b | 70 | * |
ImranBilalButt | 0:5f745af3ec9b | 71 | * @param root_ca_pem Root CA Certificate in PEM format |
ImranBilalButt | 0:5f745af3ec9b | 72 | */ |
ImranBilalButt | 0:5f745af3ec9b | 73 | nsapi_error_t set_root_ca_cert(const char *root_ca_pem); |
ImranBilalButt | 0:5f745af3ec9b | 74 | |
ImranBilalButt | 0:5f745af3ec9b | 75 | /** Sets client certificate, and client private key. |
ImranBilalButt | 0:5f745af3ec9b | 76 | * |
ImranBilalButt | 0:5f745af3ec9b | 77 | * @param client_cert Client certification in any mbed-TLS supported format. |
ImranBilalButt | 0:5f745af3ec9b | 78 | * @param client_private_key Client private key in PEM format. |
ImranBilalButt | 0:5f745af3ec9b | 79 | */ |
ImranBilalButt | 0:5f745af3ec9b | 80 | nsapi_error_t set_client_cert_key(const void *client_cert_pem, size_t client_cert_len, |
ImranBilalButt | 0:5f745af3ec9b | 81 | const void *client_private_key_pem, size_t client_private_key_len); |
ImranBilalButt | 0:5f745af3ec9b | 82 | |
ImranBilalButt | 0:5f745af3ec9b | 83 | /** Sets client certificate, and client private key. |
ImranBilalButt | 0:5f745af3ec9b | 84 | * |
ImranBilalButt | 0:5f745af3ec9b | 85 | * @param client_cert_pem Client certification in PEM format. |
ImranBilalButt | 0:5f745af3ec9b | 86 | * @param client_private_key Client private key in PEM format. |
ImranBilalButt | 0:5f745af3ec9b | 87 | */ |
ImranBilalButt | 0:5f745af3ec9b | 88 | nsapi_error_t set_client_cert_key(const char *client_cert_pem, const char *client_private_key_pem); |
ImranBilalButt | 0:5f745af3ec9b | 89 | |
ImranBilalButt | 1:a6995e66c9f7 | 90 | int set_client1_kpsa_kpsaID_cipher(); |
ImranBilalButt | 1:a6995e66c9f7 | 91 | int set_client2_kpsa_kpsaID_cipher(); |
ImranBilalButt | 0:5f745af3ec9b | 92 | /** Initiates TLS Handshake |
ImranBilalButt | 0:5f745af3ec9b | 93 | * |
ImranBilalButt | 0:5f745af3ec9b | 94 | * Initiates a TLS hanshake to a remote speer |
ImranBilalButt | 0:5f745af3ec9b | 95 | * Underlying transport socket should already be connected |
ImranBilalButt | 0:5f745af3ec9b | 96 | * |
ImranBilalButt | 0:5f745af3ec9b | 97 | * Root CA certification must be set by set_ssl_ca_pem() before |
ImranBilalButt | 0:5f745af3ec9b | 98 | * call this function. |
ImranBilalButt | 0:5f745af3ec9b | 99 | * |
ImranBilalButt | 0:5f745af3ec9b | 100 | * @return 0 on success, negative error code on failure |
ImranBilalButt | 0:5f745af3ec9b | 101 | */ |
ImranBilalButt | 0:5f745af3ec9b | 102 | nsapi_error_t do_handshake(); |
ImranBilalButt | 0:5f745af3ec9b | 103 | |
ImranBilalButt | 0:5f745af3ec9b | 104 | /** Send data over a TLS socket |
ImranBilalButt | 0:5f745af3ec9b | 105 | * |
ImranBilalButt | 0:5f745af3ec9b | 106 | * The socket must be connected to a remote host. Returns the number of |
ImranBilalButt | 0:5f745af3ec9b | 107 | * bytes sent from the buffer. |
ImranBilalButt | 0:5f745af3ec9b | 108 | * |
ImranBilalButt | 0:5f745af3ec9b | 109 | * @param data Buffer of data to send to the host |
ImranBilalButt | 0:5f745af3ec9b | 110 | * @param size Size of the buffer in bytes |
ImranBilalButt | 0:5f745af3ec9b | 111 | * @return Number of sent bytes on success, negative error |
ImranBilalButt | 0:5f745af3ec9b | 112 | * code on failure |
ImranBilalButt | 0:5f745af3ec9b | 113 | */ |
ImranBilalButt | 0:5f745af3ec9b | 114 | virtual nsapi_error_t send(const void *data, nsapi_size_t size); |
ImranBilalButt | 0:5f745af3ec9b | 115 | |
ImranBilalButt | 0:5f745af3ec9b | 116 | /** Receive data over a TLS socket |
ImranBilalButt | 0:5f745af3ec9b | 117 | * |
ImranBilalButt | 0:5f745af3ec9b | 118 | * The socket must be connected to a remote host. Returns the number of |
ImranBilalButt | 0:5f745af3ec9b | 119 | * bytes received into the buffer. |
ImranBilalButt | 0:5f745af3ec9b | 120 | * |
ImranBilalButt | 0:5f745af3ec9b | 121 | * @param data Destination buffer for data received from the host |
ImranBilalButt | 0:5f745af3ec9b | 122 | * @param size Size of the buffer in bytes |
ImranBilalButt | 0:5f745af3ec9b | 123 | * @return Number of received bytes on success, negative error |
ImranBilalButt | 0:5f745af3ec9b | 124 | * code on failure. If no data is available to be received |
ImranBilalButt | 0:5f745af3ec9b | 125 | * and the peer has performed an orderly shutdown, |
ImranBilalButt | 0:5f745af3ec9b | 126 | * recv() returns 0. |
ImranBilalButt | 0:5f745af3ec9b | 127 | */ |
ImranBilalButt | 0:5f745af3ec9b | 128 | virtual nsapi_size_or_error_t recv(void *data, nsapi_size_t size); |
ImranBilalButt | 0:5f745af3ec9b | 129 | |
ImranBilalButt | 0:5f745af3ec9b | 130 | virtual nsapi_error_t close(); |
ImranBilalButt | 0:5f745af3ec9b | 131 | virtual nsapi_error_t connect(const SocketAddress &address); |
ImranBilalButt | 0:5f745af3ec9b | 132 | virtual nsapi_size_or_error_t sendto(const SocketAddress &address, const void *data, nsapi_size_t size); |
ImranBilalButt | 0:5f745af3ec9b | 133 | virtual nsapi_size_or_error_t recvfrom(SocketAddress *address, |
ImranBilalButt | 0:5f745af3ec9b | 134 | void *data, nsapi_size_t size); |
ImranBilalButt | 0:5f745af3ec9b | 135 | virtual nsapi_error_t bind(const SocketAddress &address); |
ImranBilalButt | 0:5f745af3ec9b | 136 | virtual void set_blocking(bool blocking); |
ImranBilalButt | 0:5f745af3ec9b | 137 | virtual void set_timeout(int timeout); |
ImranBilalButt | 0:5f745af3ec9b | 138 | virtual void sigio(mbed::Callback<void()> func); |
ImranBilalButt | 0:5f745af3ec9b | 139 | virtual nsapi_error_t setsockopt(int level, int optname, const void *optval, unsigned optlen); |
ImranBilalButt | 0:5f745af3ec9b | 140 | virtual nsapi_error_t getsockopt(int level, int optname, void *optval, unsigned *optlen); |
ImranBilalButt | 0:5f745af3ec9b | 141 | virtual Socket *accept(nsapi_error_t *error = NULL); |
ImranBilalButt | 0:5f745af3ec9b | 142 | virtual nsapi_error_t listen(int backlog = 1); |
ImranBilalButt | 0:5f745af3ec9b | 143 | |
ImranBilalButt | 0:5f745af3ec9b | 144 | protected: |
ImranBilalButt | 0:5f745af3ec9b | 145 | /** |
ImranBilalButt | 0:5f745af3ec9b | 146 | * Helper for pretty-printing mbed TLS error codes |
ImranBilalButt | 0:5f745af3ec9b | 147 | */ |
ImranBilalButt | 0:5f745af3ec9b | 148 | static void print_mbedtls_error(const char *name, int err); |
ImranBilalButt | 0:5f745af3ec9b | 149 | |
ImranBilalButt | 0:5f745af3ec9b | 150 | //#if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 |
ImranBilalButt | 0:5f745af3ec9b | 151 | /** |
ImranBilalButt | 0:5f745af3ec9b | 152 | * Debug callback for mbed TLS |
ImranBilalButt | 0:5f745af3ec9b | 153 | * Just prints on the USB serial port |
ImranBilalButt | 0:5f745af3ec9b | 154 | */ |
ImranBilalButt | 0:5f745af3ec9b | 155 | static void my_debug(void *ctx, int level, const char *file, int line, |
ImranBilalButt | 0:5f745af3ec9b | 156 | const char *str); |
ImranBilalButt | 0:5f745af3ec9b | 157 | /** |
ImranBilalButt | 0:5f745af3ec9b | 158 | * Certificate verification callback for mbed TLS |
ImranBilalButt | 0:5f745af3ec9b | 159 | * Here we only use it to display information on each cert in the chain |
ImranBilalButt | 0:5f745af3ec9b | 160 | */ |
ImranBilalButt | 0:5f745af3ec9b | 161 | static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags); |
ImranBilalButt | 0:5f745af3ec9b | 162 | //#endif /* MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 */ |
ImranBilalButt | 0:5f745af3ec9b | 163 | |
ImranBilalButt | 0:5f745af3ec9b | 164 | /** |
ImranBilalButt | 0:5f745af3ec9b | 165 | * Receive callback for Mbed TLS |
ImranBilalButt | 0:5f745af3ec9b | 166 | */ |
ImranBilalButt | 0:5f745af3ec9b | 167 | static int ssl_recv(void *ctx, unsigned char *buf, size_t len); |
ImranBilalButt | 0:5f745af3ec9b | 168 | |
ImranBilalButt | 0:5f745af3ec9b | 169 | /** |
ImranBilalButt | 0:5f745af3ec9b | 170 | * Send callback for Mbed TLS |
ImranBilalButt | 0:5f745af3ec9b | 171 | */ |
ImranBilalButt | 0:5f745af3ec9b | 172 | static int ssl_send(void *ctx, const unsigned char *buf, size_t len); |
ImranBilalButt | 0:5f745af3ec9b | 173 | |
ImranBilalButt | 0:5f745af3ec9b | 174 | private: |
ImranBilalButt | 0:5f745af3ec9b | 175 | bool _client_auth; |
ImranBilalButt | 0:5f745af3ec9b | 176 | bool _keep_transport_open; |
ImranBilalButt | 0:5f745af3ec9b | 177 | bool _handshake_completed; |
ImranBilalButt | 0:5f745af3ec9b | 178 | Socket *_transport; |
ImranBilalButt | 0:5f745af3ec9b | 179 | |
ImranBilalButt | 0:5f745af3ec9b | 180 | mbedtls_entropy_context* _entropy; |
ImranBilalButt | 0:5f745af3ec9b | 181 | mbedtls_ctr_drbg_context* _ctr_drbg; |
ImranBilalButt | 0:5f745af3ec9b | 182 | mbedtls_x509_crt* _cacert; |
ImranBilalButt | 0:5f745af3ec9b | 183 | mbedtls_x509_crt* _clicert; |
ImranBilalButt | 0:5f745af3ec9b | 184 | mbedtls_pk_context* _pkctx; |
ImranBilalButt | 0:5f745af3ec9b | 185 | mbedtls_ssl_context* _ssl; |
ImranBilalButt | 0:5f745af3ec9b | 186 | mbedtls_ssl_config* _ssl_conf; |
ImranBilalButt | 0:5f745af3ec9b | 187 | struct mbedtls_timing_delay_context *_ssl_timer; |
ImranBilalButt | 0:5f745af3ec9b | 188 | |
ImranBilalButt | 0:5f745af3ec9b | 189 | /* Allocates required memory */ |
ImranBilalButt | 0:5f745af3ec9b | 190 | void tls_init(void); |
ImranBilalButt | 0:5f745af3ec9b | 191 | /* Frees memory */ |
ImranBilalButt | 0:5f745af3ec9b | 192 | void tls_free(void); |
ImranBilalButt | 0:5f745af3ec9b | 193 | /* Returns true if TLS context is allocated, false if freed */ |
ImranBilalButt | 0:5f745af3ec9b | 194 | bool is_tls_allocated(); |
ImranBilalButt | 0:5f745af3ec9b | 195 | }; |
ImranBilalButt | 0:5f745af3ec9b | 196 | |
ImranBilalButt | 0:5f745af3ec9b | 197 | #endif // _MBED_HTTPS_TLS_SOCKET_WRAPPER_H_ |