Files
DedicatedServerCourse/Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/crt/io/TlsOptions.h

454 lines
19 KiB
C
Raw Normal View History

#pragma once
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/crt/Types.h>
#include <aws/crt/io/ChannelHandler.h>
#include <aws/io/tls_channel_handler.h>
#include <functional>
#include <memory>
struct aws_tls_ctx_options;
namespace Aws
{
namespace Crt
{
namespace Io
{
class Pkcs11Lib;
class TlsContextPkcs11Options;
enum class TlsMode
{
CLIENT,
SERVER,
};
/**
* Top-level tls configuration options. These options are used to create a context from which
* per-connection TLS contexts can be created.
*/
class AWS_CRT_CPP_API TlsContextOptions
{
friend class TlsContext;
public:
TlsContextOptions() noexcept;
virtual ~TlsContextOptions();
TlsContextOptions(const TlsContextOptions &) noexcept = delete;
TlsContextOptions &operator=(const TlsContextOptions &) noexcept = delete;
TlsContextOptions(TlsContextOptions &&) noexcept;
TlsContextOptions &operator=(TlsContextOptions &&) noexcept;
/**
* @return true if the instance is in a valid state, false otherwise.
*/
explicit operator bool() const noexcept { return m_isInit; }
/**
* @return the value of the last aws error encountered by operations on this instance.
*/
int LastError() const noexcept;
/**
* Initializes TlsContextOptions with secure by default options, with
* no client certificates.
*/
static TlsContextOptions InitDefaultClient(Allocator *allocator = ApiAllocator()) noexcept;
/**
* Initializes TlsContextOptions for mutual TLS (mTLS), with
* client certificate and private key. These are paths to a file on disk. These files
* must be in the PEM format.
*
* NOTE: This is unsupported on iOS.
*
* @param cert_path: Path to certificate file.
* @param pkey_path: Path to private key file.
* @param allocator Memory allocator to use.
*/
static TlsContextOptions InitClientWithMtls(
const char *cert_path,
const char *pkey_path,
Allocator *allocator = ApiAllocator()) noexcept;
/**
* Initializes TlsContextOptions for mutual TLS (mTLS), with
* client certificate and private key. These are in memory buffers. These buffers
* must be in the PEM format.
*
* NOTE: This is unsupported on iOS.
*
* @param cert: Certificate contents in memory.
* @param pkey: Private key contents in memory.
* @param allocator Memory allocator to use.
*/
static TlsContextOptions InitClientWithMtls(
const ByteCursor &cert,
const ByteCursor &pkey,
Allocator *allocator = ApiAllocator()) noexcept;
/**
* Initializes TlsContextOptions for mutual TLS (mTLS),
* using a PKCS#11 library for private key operations.
*
* NOTE: This only works on Unix devices.
*
* @param pkcs11Options PKCS#11 options
* @param allocator Memory allocator to use.
*/
static TlsContextOptions InitClientWithMtlsPkcs11(
const TlsContextPkcs11Options &pkcs11Options,
Allocator *allocator = ApiAllocator()) noexcept;
/**
* Initializes TlsContextOptions for mutual TLS (mTLS), with
* client certificate and private key in the PKCS#12 format.
*
* NOTE: This only works on Apple devices.
*
* @param pkcs12_path: Path to PKCS #12 file. The file is loaded from disk and stored internally. It
* must remain in memory for the lifetime of the returned object.
* @param pkcs12_pwd: Password to PKCS #12 file. It must remain in memory for the lifetime of the
* returned object.
* @param allocator Memory allocator to use.
*/
static TlsContextOptions InitClientWithMtlsPkcs12(
const char *pkcs12_path,
const char *pkcs12_pwd,
Allocator *allocator = ApiAllocator()) noexcept;
/**
* @deprecated Custom keychain management is deprecated.
*
* By default the certificates and private keys are stored in the default keychain
* of the account of the process. If you instead wish to provide your own keychain
* for storing them, this makes the TlsContext to use that instead.
* NOTE: The password of your keychain must be empty.
*
* NOTE: This only works on MacOS.
*/
bool SetKeychainPath(ByteCursor &keychain_path) noexcept;
/**
* Initializes TlsContextOptions for mutual TLS (mTLS),
* using a client certificate in a Windows certificate store.
*
* NOTE: This only works on Windows.
*
* @param windowsCertStorePath Path to certificate in a Windows certificate store.
* The path must use backslashes and end with the certificate's thumbprint.
* Example: `CurrentUser\MY\A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6`
* @param allocator The memory allocator to use.
*/
static TlsContextOptions InitClientWithMtlsSystemPath(
const char *windowsCertStorePath,
Allocator *allocator = ApiAllocator()) noexcept;
/**
* @return true if alpn is supported by the underlying security provider, false
* otherwise.
*/
static bool IsAlpnSupported() noexcept;
/**
* Sets the list of alpn protocols.
* @param alpnList: List of protocol names, delimited by ';'. This string must remain in memory for the
* lifetime of this object.
*/
bool SetAlpnList(const char *alpnList) noexcept;
/**
* In client mode, this turns off x.509 validation. Don't do this unless you're testing.
* It's much better, to just override the default trust store and pass the self-signed
* certificate as the caFile argument.
*
* In server mode, this defaults to false. If you want to support mutual TLS from the server,
* you'll want to set this to true.
*/
void SetVerifyPeer(bool verifyPeer) noexcept;
/**
* Sets the minimum TLS version allowed.
* @param minimumTlsVersion: The minimum TLS version.
*/
void SetMinimumTlsVersion(aws_tls_versions minimumTlsVersion);
/**
* Sets the preferred TLS Cipher List
* @param cipher_pref: The preferred TLS cipher list.
*/
void SetTlsCipherPreference(aws_tls_cipher_pref cipher_pref);
/**
* Overrides the default system trust store.
* @param caPath: Path to directory containing trusted certificates, which will overrides the
* default trust store. Only useful on Unix style systems where all anchors are stored in a directory
* (like /etc/ssl/certs). This string must remain in memory for the lifetime of this object.
* @param caFile: Path to file containing PEM armored chain of trusted CA certificates. This
* string must remain in memory for the lifetime of this object.
*/
bool OverrideDefaultTrustStore(const char *caPath, const char *caFile) noexcept;
/**
* Overrides the default system trust store.
* @param ca: PEM armored chain of trusted CA certificates.
*/
bool OverrideDefaultTrustStore(const ByteCursor &ca) noexcept;
/// @private
const aws_tls_ctx_options *GetUnderlyingHandle() const noexcept { return &m_options; }
private:
aws_tls_ctx_options m_options;
bool m_isInit;
};
/**
* Options for TLS, when using a PKCS#11 library for private key operations.
*
* @see TlsContextOptions::InitClientWithMtlsPkcs11()
*/
class AWS_CRT_CPP_API TlsContextPkcs11Options final
{
public:
/**
* @param pkcs11Lib use this PKCS#11 library
* @param allocator Memory allocator to use.
*/
TlsContextPkcs11Options(
const std::shared_ptr<Pkcs11Lib> &pkcs11Lib,
Allocator *allocator = ApiAllocator()) noexcept;
/**
* Use this PIN to log the user into the PKCS#11 token.
* Leave unspecified to log into a token with a "protected authentication path".
*
* @param pin PIN
*/
void SetUserPin(const String &pin) noexcept;
/**
* Specify the slot ID containing a PKCS#11 token.
* If not specified, the token will be chosen based on other criteria (such as token label).
*
* @param id slot ID
*/
void SetSlotId(const uint64_t id) noexcept;
/**
* Specify the label of the PKCS#11 token to use.
* If not specified, the token will be chosen based on other criteria (such as slot ID).
*
* @param label label of token
*/
void SetTokenLabel(const String &label) noexcept;
/**
* Specify the label of the private key object on the PKCS#11 token.
* If not specified, the key will be chosen based on other criteria
* (such as being the only available private key on the token).
*
* @param label label of private key object
*/
void SetPrivateKeyObjectLabel(const String &label) noexcept;
/**
* Use this X.509 certificate (file on disk).
* The certificate may be specified by other means instead (ex: SetCertificateFileContents())
*
* @param path path to PEM-formatted certificate file on disk.
*/
void SetCertificateFilePath(const String &path) noexcept;
/**
* Use this X.509 certificate (contents in memory).
* The certificate may be specified by other means instead (ex: SetCertificateFilePath())
*
* @param contents contents of PEM-formatted certificate file.
*/
void SetCertificateFileContents(const String &contents) noexcept;
/// @private
aws_tls_ctx_pkcs11_options GetUnderlyingHandle() const noexcept;
private:
std::shared_ptr<Pkcs11Lib> m_pkcs11Lib;
Optional<uint64_t> m_slotId;
Optional<String> m_userPin;
Optional<String> m_tokenLabel;
Optional<String> m_privateKeyObjectLabel;
Optional<String> m_certificateFilePath;
Optional<String> m_certificateFileContents;
};
/**
* Options specific to a single connection.
*/
class AWS_CRT_CPP_API TlsConnectionOptions final
{
public:
TlsConnectionOptions() noexcept;
~TlsConnectionOptions();
TlsConnectionOptions(const TlsConnectionOptions &) noexcept;
TlsConnectionOptions &operator=(const TlsConnectionOptions &) noexcept;
TlsConnectionOptions(TlsConnectionOptions &&options) noexcept;
TlsConnectionOptions &operator=(TlsConnectionOptions &&options) noexcept;
/**
* Sets SNI extension, and also the name used for X.509 validation. serverName is copied.
*
* @return true if the copy succeeded, or false otherwise.
*/
bool SetServerName(ByteCursor &serverName) noexcept;
/**
* Sets list of protocols (semi-colon delimited in priority order) used for ALPN extension.
* alpnList is copied.
*
* @return true if the copy succeeded, or false otherwise.
*/
bool SetAlpnList(const char *alpnList) noexcept;
/**
* @return true if the instance is in a valid state, false otherwise.
*/
explicit operator bool() const noexcept { return isValid(); }
/**
* @return the value of the last aws error encountered by operations on this instance.
*/
int LastError() const noexcept { return m_lastError; }
/// @private
const aws_tls_connection_options *GetUnderlyingHandle() const noexcept
{
return &m_tls_connection_options;
}
private:
bool isValid() const noexcept { return m_isInit; }
TlsConnectionOptions(aws_tls_ctx *ctx, Allocator *allocator) noexcept;
aws_tls_connection_options m_tls_connection_options;
aws_allocator *m_allocator;
int m_lastError;
bool m_isInit;
friend class TlsContext;
};
/**
* Stateful context for TLS with a given configuration. Per-connection TLS "contexts"
* (TlsConnectionOptions) are instantiated from this as needed.
*/
class AWS_CRT_CPP_API TlsContext final
{
public:
TlsContext() noexcept;
TlsContext(TlsContextOptions &options, TlsMode mode, Allocator *allocator = ApiAllocator()) noexcept;
~TlsContext() = default;
TlsContext(const TlsContext &) noexcept = default;
TlsContext &operator=(const TlsContext &) noexcept = default;
TlsContext(TlsContext &&) noexcept = default;
TlsContext &operator=(TlsContext &&) noexcept = default;
/**
* @return a new connection-specific TLS context that can be configured with per-connection options
* (server name, peer verification, etc...)
*/
TlsConnectionOptions NewConnectionOptions() const noexcept;
/**
* @return true if the instance is in a valid state, false otherwise.
*/
explicit operator bool() const noexcept { return isValid(); }
/**
* @return the value of the last aws error encountered by operations on this instance.
*/
int GetInitializationError() const noexcept { return m_initializationError; }
/// @private
aws_tls_ctx *GetUnderlyingHandle() const noexcept { return m_ctx.get(); }
private:
bool isValid() const noexcept { return m_ctx && m_initializationError == AWS_ERROR_SUCCESS; }
std::shared_ptr<aws_tls_ctx> m_ctx;
int m_initializationError;
};
using NewTlsContextImplCallback = std::function<void *(TlsContextOptions &, TlsMode, Allocator *)>;
using DeleteTlsContextImplCallback = std::function<void(void *)>;
using IsTlsAlpnSupportedCallback = std::function<bool()>;
/**
* BYO_CRYPTO: TLS channel-handler base class.
*/
class AWS_CRT_CPP_API TlsChannelHandler : public ChannelHandler
{
public:
virtual ~TlsChannelHandler();
/**
* @return negotiated protocol (or empty string if no agreed upon protocol)
*/
virtual String GetProtocol() const = 0;
protected:
TlsChannelHandler(
struct aws_channel_slot *slot,
const struct aws_tls_connection_options &options,
Allocator *allocator = ApiAllocator());
/**
* Invoke this function from inside your handler after TLS negotiation completes. errorCode ==
* AWS_ERROR_SUCCESS or 0 means the session was successfully established and the connection should
* continue on.
*/
void CompleteTlsNegotiation(int errorCode);
private:
aws_tls_on_negotiation_result_fn *m_OnNegotiationResult;
void *m_userData;
aws_byte_buf m_protocolByteBuf;
friend aws_byte_buf(::aws_tls_handler_protocol)(aws_channel_handler *);
};
/**
* BYO_CRYPTO: Client TLS channel-handler base class.
*
* If using BYO_CRYPTO, you must define a concrete implementation
* and set its creation callback via ApiHandle.SetBYOCryptoClientTlsCallback().
*/
class AWS_CRT_CPP_API ClientTlsChannelHandler : public TlsChannelHandler
{
public:
/**
* Initiates the TLS session negotiation. This is called by the common runtime when it's time to start
* a new session.
*/
virtual void StartNegotiation() = 0;
protected:
ClientTlsChannelHandler(
struct aws_channel_slot *slot,
const struct aws_tls_connection_options &options,
Allocator *allocator = ApiAllocator());
};
using NewClientTlsHandlerCallback = std::function<std::shared_ptr<ClientTlsChannelHandler>(
struct aws_channel_slot *slot,
const struct aws_tls_connection_options &options,
Allocator *allocator)>;
} // namespace Io
} // namespace Crt
} // namespace Aws