This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
powersync-core/libguh-core/MbedTLS/MbedTLSConnection.hpp
2019-04-02 01:02:45 +02:00

184 lines
8.0 KiB
C++

/*
* Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.
*/
/**
* @file MbedTLSConnection.hpp
* @brief Defines a reference implementation for an MbedTLS library wrapper *
*/
#pragma once
#include <atomic>
#include "mbedtls/config.h"
#include "mbedtls/platform.h"
#ifdef MBEDTLS_NEW_HEADERS
#include "mbedtls/net_sockets.h"
#else
#include "mbedtls/net.h"
#endif
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include "mbedtls/timing.h"
#include "NetworkConnection.hpp"
#include "ResponseCode.hpp"
namespace awsiotsdk {
namespace network {
/**
* @brief MbedTLS Wrapper Class
*
* Defines a reference wrapper for MbedTLS libraries
*/
class MbedTLSConnection : public NetworkConnection {
protected:
util::String root_ca_location_; ///< Pointer to string containing the filename (including path) of the root CA file.
util::String device_cert_location_; ///< Pointer to string containing the filename (including path) of the device certificate.
util::String device_private_key_location_; ///< Pointer to string containing the filename (including path) of the device private key file.
std::atomic_bool server_verification_flag_; ///< Boolean. True = perform server certificate hostname validation. False = skip validation \b NOT recommended.
std::atomic_bool is_connected_; ///< Boolean indicating connection status
std::chrono::milliseconds tls_handshake_timeout_; ///< Timeout for TLS handshake command
std::chrono::milliseconds tls_read_timeout_; ///< Timeout for the TLS Read command
std::chrono::milliseconds tls_write_timeout_; ///< Timeout for the TLS Write command
// Endpoint information
uint16_t endpoint_port_; ///< Endpoint port
util::String endpoint_; ///< Endpoint for this connection
mbedtls_entropy_context entropy_;
mbedtls_ctr_drbg_context ctr_drbg_;
mbedtls_ssl_context ssl_;
mbedtls_ssl_config conf_;
uint32_t flags_;
mbedtls_x509_crt cacert_;
mbedtls_x509_crt clicert_;
mbedtls_pk_context pkey_;
mbedtls_net_context server_fd_;
// TODO: This is a Hotfix, requires a better approach
std::atomic_bool requires_free_; ///< Boolean indicating whether the mbedtls struct variables have been allocated or not
/**
* @brief Create a TLS socket and open the connection
*
* Creates an open socket connection including TLS handshake.
*
* @return ResponseCode - successful connection or TLS error
*/
ResponseCode ConnectInternal();
/**
* @brief Write bytes to the network socket
*
* @param util::String - const reference to buffer which should be written to socket
* @return size_t - number of bytes written or Network error
* @return ResponseCode - successful write or Network error code
*/
ResponseCode WriteInternal(const util::String &buf, size_t &size_written_bytes_out);
/**
* @brief Read bytes from the network socket
*
* @param util::String - reference to buffer where read bytes should be copied
* @param size_t - number of bytes to read
* @param size_t - reference to store number of bytes read
* @return ResponseCode - successful read or TLS error code
*/
ResponseCode ReadInternal(util::Vector<unsigned char> &buf, size_t buf_read_offset,
size_t size_bytes_to_read, size_t &size_read_bytes_out);
/**
* @brief Disconnect from network socket
*
* @return ResponseCode - successful read or TLS error code
*/
ResponseCode DisconnectInternal();
public:
static int VerifyCertificate(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags);
/**
* @brief Constructor for the MbedTLS TLS implementation
*
* Performs any initialization required by the TLS layer.
*
* @param util::String endpoint - The target endpoint to connect to
* @param uint16_t endpoint_port - The port on the target to connect to
* @param util::String root_ca_location - Path of the location of the Root CA
* @param util::String device_cert_location - Path to the location of the Device Cert
* @param util::String device_private_key_location - Path to the location of the device private key file
* @param std::chrono::milliseconds tls_handshake_timeout - The value to use for timeout of handshake operation
* @param std::chrono::milliseconds tls_read_timeout - The value to use for timeout of read operation
* @param std::chrono::milliseconds tls_write_timeout - The value to use for timeout of write operation
* @param bool server_verification_flag - used to decide whether server verification is needed or not
*
*/
MbedTLSConnection(util::String endpoint, uint16_t endpoint_port, util::String root_ca_location,
util::String device_cert_location, util::String device_private_key_location,
std::chrono::milliseconds tls_handshake_timeout,
std::chrono::milliseconds tls_read_timeout, std::chrono::milliseconds tls_write_timeout,
bool server_verification_flag);
/**
* @brief Check if TLS layer is still connected
*
* Called to check if the TLS layer is still connected or not.
*
* @return bool - indicating status of network TLS layer connection
*/
bool IsConnected();
/**
* @brief Check if Network Physical layer is still connected
*
* Called to check if the Network Physical layer is still connected or not.
*
* @return bool - indicating status of network physical layer connection
*/
bool IsPhysicalLayerConnected();
/**
* @brief sets the path to the root CA
*
* Called to change the location of the root CA after the constructor has initialized the OpenSSL object.
*
* @param root_ca_location
*/
void SetRootCAPath(util::String root_ca_location) { root_ca_location_ = root_ca_location; }
/**
* @brief sets the endpoint and the port
*
* Called to change the endpoint and the port after the constructor has initialized the OpenSSL object.
* @param endpoint
* @param endpoint_port
*/
void SetEndpointAndPort(util::String endpoint, uint16_t endpoint_port) {
endpoint_ = endpoint;
endpoint_port_ = endpoint_port;
}
virtual ~MbedTLSConnection();
};
}
}