..
Diff: TLSSocketWrapper.h
- Revision:
- 0:5f745af3ec9b
--- /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_