[secure-transport] introduce SecureSession class (#11046)

This commit introduces the `SecureSession` class to manage
session-related functionality, decoupling it from the
`SecureTransport` class. `SecureSession` provides method such as
`Connect()`, `Send()`, and `IsConnected()`, while `SecureTransport`
focuses on transport-level operations and common configuration
(e.g., setting PSK, cipher keys).

The `Dtls` and `Tls` subclasses now inherit from both
`SecureTransport` and `SecureSession`, effectively providing the same
methods as before and implementing a single DTLS/TLS session over a
socket.
This commit is contained in:
Abtin Keshavarzian
2024-12-17 22:01:31 -08:00
committed by GitHub
parent 35608703f7
commit 4e9d362b67
2 changed files with 403 additions and 290 deletions
+212 -158
View File
@@ -81,16 +81,12 @@ SecureTransport::SecureTransport(Instance &aInstance, LinkSecurityMode aLayerTwo
, mDatagramTransport(aDatagramTransport)
, mIsOpen(false)
, mIsServer(true)
, mTimerSet(false)
, mVerifyPeerCertificate(true)
, mSessionState(kSessionDisconnected)
, mCipherSuite(kUnspecifiedCipherSuite)
, mMessageSubType(Message::kSubTypeNone)
, mConnectEvent(kDisconnectedError)
, mPskLength(0)
, mMaxConnectionAttempts(0)
, mRemainingConnectionAttempts(0)
, mReceiveMessage(nullptr)
, mSession(nullptr)
, mSocket(aInstance, *this)
, mTimer(aInstance, SecureTransport::HandleTimer, this)
#if OPENTHREAD_CONFIG_TLS_API_ENABLE
@@ -98,44 +94,56 @@ SecureTransport::SecureTransport(Instance &aInstance, LinkSecurityMode aLayerTwo
#endif
{
ClearAllBytes(mPsk);
OT_UNUSED_VARIABLE(mVerifyPeerCertificate);
}
SecureSession::SecureSession(SecureTransport &aTransport)
: mTimerSet(false)
, mState(kStateDisconnected)
, mMessageSubType(Message::kSubTypeNone)
, mConnectEvent(kDisconnectedError)
, mTransport(aTransport)
, mReceiveMessage(nullptr)
{
ClearAllBytes(mSsl);
ClearAllBytes(mConf);
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
ClearAllBytes(mCookieCtx);
#endif
}
void SecureTransport::FreeMbedtls(void)
void SecureSession::FreeMbedtls(void)
{
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
if (mDatagramTransport)
if (mTransport.mDatagramTransport)
{
mbedtls_ssl_cookie_free(&mCookieCtx);
}
#endif
#if OPENTHREAD_CONFIG_TLS_API_ENABLE && defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
if (mExtension != nullptr)
if (mTransport.mExtension != nullptr)
{
mExtension->mEcdheEcdsaInfo.Free();
mTransport.mExtension->mEcdheEcdsaInfo.Free();
}
#endif
mbedtls_ssl_config_free(&mConf);
mbedtls_ssl_free(&mSsl);
}
void SecureTransport::SetSessionState(SessionState aSessionState)
void SecureSession::SetState(State aState)
{
VerifyOrExit(mSessionState != aSessionState);
VerifyOrExit(mState != aState);
LogInfo("State: %s -> %s", SessionStateToString(mSessionState), SessionStateToString(aSessionState));
mSessionState = aSessionState;
LogInfo("Session state: %s -> %s", StateToString(mState), StateToString(aState));
mState = aState;
exit:
return;
}
Error SecureTransport::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext)
Error SecureTransport::Open(SecureSession::ReceiveHandler aReceiveHandler,
SecureSession::ConnectedHandler aConnectedHandler,
void *aContext)
{
Error error;
@@ -144,13 +152,11 @@ Error SecureTransport::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aCo
SuccessOrExit(error = mSocket.Open(Ip6::kNetifUnspecified));
mIsOpen = true;
mConnectedCallback.Set(aConnectedHandler, aContext);
mReceiveCallback.Set(aReceiveHandler, aContext);
mSession->SetConnectedCallback(aConnectedHandler, aContext);
mSession->SetReceiveCallback(aReceiveHandler, aContext);
mRemainingConnectionAttempts = mMaxConnectionAttempts;
SetSessionState(kSessionDisconnected);
exit:
return error;
}
@@ -168,22 +174,18 @@ exit:
return error;
}
Error SecureTransport::Connect(const Ip6::SockAddr &aSockAddr)
Error SecureSession::Connect(const Ip6::SockAddr &aSockAddr)
{
Error error;
VerifyOrExit(mIsOpen, error = kErrorInvalidState);
VerifyOrExit(IsSessionDisconnected(), error = kErrorInvalidState);
if (mRemainingConnectionAttempts > 0)
{
mRemainingConnectionAttempts--;
}
VerifyOrExit(mTransport.mIsOpen, error = kErrorInvalidState);
VerifyOrExit(IsDisconnected(), error = kErrorInvalidState);
mTransport.DecremenetRemainingConnectionAttempts();
mMessageInfo.SetPeerAddr(aSockAddr.GetAddress());
mMessageInfo.SetPeerPort(aSockAddr.mPort);
mIsServer = false;
mTransport.mIsServer = false;
error = Setup();
@@ -195,12 +197,22 @@ void SecureTransport::HandleReceive(Message &aMessage, const Ip6::MessageInfo &a
{
VerifyOrExit(mIsOpen);
if (IsSessionDisconnected())
if (!mSession->IsDisconnected())
{
if (mRemainingConnectionAttempts > 0)
{
mRemainingConnectionAttempts--;
}
VerifyOrExit(mSession->Matches(aMessageInfo));
}
mSession->HandleTransportReceive(aMessage, aMessageInfo);
exit:
return;
}
void SecureSession::HandleTransportReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
if (IsDisconnected())
{
mTransport.DecremenetRemainingConnectionAttempts();
mMessageInfo.SetPeerAddr(aMessageInfo.GetPeerAddr());
mMessageInfo.SetPeerPort(aMessageInfo.GetPeerPort());
@@ -211,14 +223,9 @@ void SecureTransport::HandleReceive(Message &aMessage, const Ip6::MessageInfo &a
SuccessOrExit(Setup());
}
else
{
// Once DTLS session is started, communicate only with a single peer.
VerifyOrExit(mMessageInfo.HasSamePeerAddrAndPort(aMessageInfo));
}
#ifdef MBEDTLS_SSL_SRV_C
if (IsSessionConnecting())
if (IsConnecting())
{
mbedtls_ssl_set_client_transport_id(&mSsl, mMessageInfo.GetPeerAddr().GetBytes(), sizeof(Ip6::Address));
}
@@ -237,9 +244,10 @@ Error SecureTransport::Bind(uint16_t aPort)
Error error;
VerifyOrExit(mIsOpen, error = kErrorInvalidState);
VerifyOrExit(IsSessionDisconnected(), error = kErrorInvalidState);
VerifyOrExit(!mTransportCallback.IsSet(), error = kErrorAlready);
VerifyOrExit(mSession->IsDisconnected(), error = kErrorInvalidState);
SuccessOrExit(error = mSocket.Bind(aPort));
mIsServer = true;
@@ -252,10 +260,11 @@ Error SecureTransport::Bind(TransportCallback aCallback, void *aContext)
Error error = kErrorNone;
VerifyOrExit(mIsOpen, error = kErrorInvalidState);
VerifyOrExit(IsSessionDisconnected(), error = kErrorInvalidState);
VerifyOrExit(!mSocket.IsBound(), error = kErrorAlready);
VerifyOrExit(!mTransportCallback.IsSet(), error = kErrorAlready);
VerifyOrExit(mSession->IsDisconnected(), error = kErrorInvalidState);
mTransportCallback.Set(aCallback, aContext);
mIsServer = true;
@@ -263,31 +272,33 @@ exit:
return error;
}
Error SecureTransport::Setup(void)
Error SecureSession::Setup(void)
{
Error error = kErrorNone;
int rval = 0;
OT_ASSERT(mCipherSuite != kUnspecifiedCipherSuite);
OT_ASSERT(mTransport.mCipherSuite != SecureTransport::kUnspecifiedCipherSuite);
VerifyOrExit(mIsOpen, error = kErrorInvalidState);
VerifyOrExit(IsSessionDisconnected(), error = kErrorBusy);
VerifyOrExit(mTransport.mIsOpen, error = kErrorInvalidState);
VerifyOrExit(IsDisconnected(), error = kErrorBusy);
SetSessionState(kSessionInitializing);
SetState(kStateInitializing);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Setup the mbedtls_ssl_config `mConf`.
mbedtls_ssl_config_init(&mConf);
rval = mbedtls_ssl_config_defaults(
&mConf, mIsServer ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
mDatagramTransport ? MBEDTLS_SSL_TRANSPORT_DATAGRAM : MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
rval = mbedtls_ssl_config_defaults(&mConf, mTransport.mIsServer ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
mTransport.mDatagramTransport ? MBEDTLS_SSL_TRANSPORT_DATAGRAM
: MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
VerifyOrExit(rval == 0);
#if OPENTHREAD_CONFIG_TLS_API_ENABLE && defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
if (mVerifyPeerCertificate &&
(mCipherSuite == kEcdheEcdsaWithAes128Ccm8 || mCipherSuite == kEcdheEcdsaWithAes128GcmSha256))
if (mTransport.mVerifyPeerCertificate &&
(mTransport.mCipherSuite == SecureTransport::kEcdheEcdsaWithAes128Ccm8 ||
mTransport.mCipherSuite == SecureTransport::kEcdheEcdsaWithAes128GcmSha256))
{
mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_REQUIRED);
}
@@ -295,8 +306,6 @@ Error SecureTransport::Setup(void)
{
mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_NONE);
}
#else
OT_UNUSED_VARIABLE(mVerifyPeerCertificate);
#endif
mbedtls_ssl_conf_rng(&mConf, Crypto::MbedTls::CryptoSecurePrng, nullptr);
@@ -318,52 +327,52 @@ Error SecureTransport::Setup(void)
struct EnumCheck
{
InitEnumValidatorCounter();
ValidateNextEnum(kEcjpakeWithAes128Ccm8);
ValidateNextEnum(SecureTransport::kEcjpakeWithAes128Ccm8);
#if OPENTHREAD_CONFIG_TLS_API_ENABLE && defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
ValidateNextEnum(kPskWithAes128Ccm8);
ValidateNextEnum(SecureTransport::kPskWithAes128Ccm8);
#endif
#if OPENTHREAD_CONFIG_TLS_API_ENABLE && defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
ValidateNextEnum(kEcdheEcdsaWithAes128Ccm8);
ValidateNextEnum(kEcdheEcdsaWithAes128GcmSha256);
ValidateNextEnum(SecureTransport::kEcdheEcdsaWithAes128Ccm8);
ValidateNextEnum(SecureTransport::kEcdheEcdsaWithAes128GcmSha256);
#endif
};
mbedtls_ssl_conf_ciphersuites(&mConf, kCipherSuites[mCipherSuite]);
mbedtls_ssl_conf_ciphersuites(&mConf, SecureTransport::kCipherSuites[mTransport.mCipherSuite]);
}
if (mCipherSuite == kEcjpakeWithAes128Ccm8)
if (mTransport.mCipherSuite == SecureTransport::kEcjpakeWithAes128Ccm8)
{
#if (MBEDTLS_VERSION_NUMBER >= 0x03010000)
mbedtls_ssl_conf_groups(&mConf, kGroups);
mbedtls_ssl_conf_groups(&mConf, SecureTransport::kGroups);
#else
mbedtls_ssl_conf_curves(&mConf, kCurves);
mbedtls_ssl_conf_curves(&mConf, SecureTransport::kCurves);
#endif
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) || defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
#if (MBEDTLS_VERSION_NUMBER >= 0x03020000)
mbedtls_ssl_conf_sig_algs(&mConf, kSignatures);
mbedtls_ssl_conf_sig_algs(&mConf, SecureTransport::kSignatures);
#else
mbedtls_ssl_conf_sig_hashes(&mConf, kHashes);
mbedtls_ssl_conf_sig_hashes(&mConf, SecureTransport::kHashes);
#endif
#endif
}
#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
mbedtls_ssl_conf_export_keys_cb(&mConf, HandleMbedtlsExportKeys, this);
mbedtls_ssl_conf_export_keys_cb(&mConf, SecureTransport::HandleMbedtlsExportKeys, &mTransport);
#endif
mbedtls_ssl_conf_handshake_timeout(&mConf, 8000, 60000);
mbedtls_ssl_conf_dbg(&mConf, HandleMbedtlsDebug, this);
mbedtls_ssl_conf_dbg(&mConf, SecureTransport::HandleMbedtlsDebug, &mTransport);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Setup the `Extension` components.
#if OPENTHREAD_CONFIG_TLS_API_ENABLE
if (mExtension != nullptr)
if (mTransport.mExtension != nullptr)
{
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
mExtension->mEcdheEcdsaInfo.Init();
mTransport.mExtension->mEcdheEcdsaInfo.Init();
#endif
rval = mExtension->SetApplicationSecureKeys();
rval = mTransport.mExtension->SetApplicationSecureKeys(mConf);
VerifyOrExit(rval == 0);
}
#endif
@@ -372,11 +381,11 @@ Error SecureTransport::Setup(void)
// Setup the mbedtls_ssl_cookie_ctx `mCookieCtx`.
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
if (mDatagramTransport)
if (mTransport.mDatagramTransport)
{
mbedtls_ssl_cookie_init(&mCookieCtx);
if (mIsServer)
if (mTransport.mIsServer)
{
rval = mbedtls_ssl_cookie_setup(&mCookieCtx, Crypto::MbedTls::CryptoSecurePrng, nullptr);
VerifyOrExit(rval == 0);
@@ -396,41 +405,41 @@ Error SecureTransport::Setup(void)
mbedtls_ssl_set_bio(&mSsl, this, HandleMbedtlsTransmit, HandleMbedtlsReceive, /* RecvTimeoutFn */ nullptr);
if (mDatagramTransport)
if (mTransport.mDatagramTransport)
{
mbedtls_ssl_set_timer_cb(&mSsl, this, HandleMbedtlsSetTimer, HandleMbedtlsGetTimer);
}
#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
mbedtls_ssl_set_export_keys_cb(&mSsl, HandleMbedtlsExportKeys, this);
mbedtls_ssl_set_export_keys_cb(&mSsl, SecureTransport::HandleMbedtlsExportKeys, &mTransport);
#endif
if (mCipherSuite == kEcjpakeWithAes128Ccm8)
if (mTransport.mCipherSuite == SecureTransport::kEcjpakeWithAes128Ccm8)
{
rval = mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
rval = mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mTransport.mPsk, mTransport.mPskLength);
VerifyOrExit(rval == 0);
}
mReceiveMessage = nullptr;
mMessageSubType = Message::kSubTypeNone;
SetSessionState(kSessionConnecting);
SetState(kStateConnecting);
Process();
exit:
if (mIsOpen && IsSessionInitializing())
if (IsInitializing())
{
error = Crypto::MbedTls::MapError(rval);
if ((mMaxConnectionAttempts > 0) && (mRemainingConnectionAttempts == 0))
if (mTransport.HasNoRemainingConnectionAttempts())
{
Close();
mAutoCloseCallback.InvokeIfSet();
mTransport.Close();
mTransport.mAutoCloseCallback.InvokeIfSet();
}
else
{
SetSessionState(kSessionDisconnected);
SetState(kStateDisconnected);
FreeMbedtls();
}
}
@@ -442,11 +451,10 @@ void SecureTransport::Close(void)
{
VerifyOrExit(mIsOpen);
Disconnect(kDisconnectedLocalClosed);
SetSessionState(kSessionDisconnected);
mSession->Disconnect(SecureSession::kDisconnectedLocalClosed);
mSession->SetState(SecureSession::kStateDisconnected);
mIsOpen = false;
mTimerSet = false;
mIsOpen = false;
mTransportCallback.Clear();
IgnoreError(mSocket.Close());
mTimer.Stop();
@@ -455,15 +463,18 @@ exit:
return;
}
void SecureTransport::Disconnect(ConnectEvent aEvent)
void SecureSession::Disconnect(ConnectEvent aEvent)
{
VerifyOrExit(mIsOpen);
VerifyOrExit(IsSessionConnectingOrConnected());
VerifyOrExit(mTransport.mIsOpen);
VerifyOrExit(IsConnectingOrConnected());
mbedtls_ssl_close_notify(&mSsl);
SetSessionState(kSessionDisconnecting);
SetState(kStateDisconnecting);
mConnectEvent = aEvent;
mTimer.Start(kGuardTimeNewConnectionMilli);
mTimerSet = false;
mTimerFinish = TimerMilli::GetNow() + kGuardTimeNewConnectionMilli;
mTransport.mTimer.FireAtIfEarlier(mTimerFinish);
mMessageInfo.Clear();
@@ -473,6 +484,19 @@ exit:
return;
}
void SecureTransport::DecremenetRemainingConnectionAttempts(void)
{
if (mRemainingConnectionAttempts > 0)
{
mRemainingConnectionAttempts--;
}
}
bool SecureTransport::HasNoRemainingConnectionAttempts(void) const
{
return (mMaxConnectionAttempts > 0) && (mRemainingConnectionAttempts == 0);
}
Error SecureTransport::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
{
Error error = kErrorNone;
@@ -487,7 +511,7 @@ exit:
return error;
}
Error SecureTransport::Send(Message &aMessage)
Error SecureSession::Send(Message &aMessage)
{
Error error = kErrorNone;
uint16_t length = aMessage.GetLength();
@@ -506,7 +530,7 @@ exit:
return error;
}
bool SecureTransport::IsMbedtlsHandshakeOver(mbedtls_ssl_context *aSslContext)
bool SecureSession::IsMbedtlsHandshakeOver(mbedtls_ssl_context *aSslContext)
{
return
#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
@@ -516,35 +540,46 @@ bool SecureTransport::IsMbedtlsHandshakeOver(mbedtls_ssl_context *aSslContext)
#endif
}
int SecureTransport::HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength)
int SecureSession::HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength)
{
return static_cast<SecureTransport *>(aContext)->HandleMbedtlsTransmit(aBuf, aLength);
return static_cast<SecureSession *>(aContext)->HandleMbedtlsTransmit(aBuf, aLength);
}
int SecureTransport::HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength)
int SecureSession::HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength)
{
Message::SubType msgSubType = mMessageSubType;
mMessageSubType = Message::kSubTypeNone;
return mTransport.Transmit(aBuf, aLength, mMessageInfo, msgSubType);
}
int SecureTransport::Transmit(const unsigned char *aBuf,
size_t aLength,
const Ip6::MessageInfo &aMessageInfo,
Message::SubType aMessageSubType)
{
Error error = kErrorNone;
Message *message = mSocket.NewMessage();
int rval;
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
message->SetSubType(mMessageSubType);
message->SetSubType(aMessageSubType);
message->SetLinkSecurityEnabled(mLayerTwoSecurity);
SuccessOrExit(error = message->AppendBytes(aBuf, static_cast<uint16_t>(aLength)));
if (mTransportCallback.IsSet())
{
error = mTransportCallback.Invoke(*message, mMessageInfo);
error = mTransportCallback.Invoke(*message, aMessageInfo);
}
else
{
error = mSocket.SendTo(*message, mMessageInfo);
error = mSocket.SendTo(*message, aMessageInfo);
}
exit:
FreeMessageOnError(message, error);
mMessageSubType = Message::kSubTypeNone;
switch (error)
{
@@ -565,12 +600,12 @@ exit:
return rval;
}
int SecureTransport::HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength)
int SecureSession::HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength)
{
return static_cast<SecureTransport *>(aContext)->HandleMbedtlsReceive(aBuf, aLength);
return static_cast<SecureSession *>(aContext)->HandleMbedtlsReceive(aBuf, aLength);
}
int SecureTransport::HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength)
int SecureSession::HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength)
{
int rval = MBEDTLS_ERR_SSL_WANT_READ;
uint16_t readLength;
@@ -587,12 +622,12 @@ exit:
return rval;
}
int SecureTransport::HandleMbedtlsGetTimer(void *aContext)
int SecureSession::HandleMbedtlsGetTimer(void *aContext)
{
return static_cast<SecureTransport *>(aContext)->HandleMbedtlsGetTimer();
return static_cast<SecureSession *>(aContext)->HandleMbedtlsGetTimer();
}
int SecureTransport::HandleMbedtlsGetTimer(void)
int SecureSession::HandleMbedtlsGetTimer(void)
{
int rval = 0;
@@ -623,17 +658,16 @@ int SecureTransport::HandleMbedtlsGetTimer(void)
return rval;
}
void SecureTransport::HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish)
void SecureSession::HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish)
{
static_cast<SecureTransport *>(aContext)->HandleMbedtlsSetTimer(aIntermediate, aFinish);
static_cast<SecureSession *>(aContext)->HandleMbedtlsSetTimer(aIntermediate, aFinish);
}
void SecureTransport::HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish)
void SecureSession::HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish)
{
if (aFinish == 0)
{
mTimerSet = false;
mTimer.Stop();
}
else
{
@@ -643,7 +677,7 @@ void SecureTransport::HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFi
mTimerIntermediate = now + aIntermediate;
mTimerFinish = now + aFinish;
mTimer.FireAt(mTimerFinish);
mTransport.mTimer.FireAtIfEarlier(mTimerFinish);
}
}
@@ -738,26 +772,47 @@ void SecureTransport::HandleTimer(Timer &aTimer)
void SecureTransport::HandleTimer(void)
{
VerifyOrExit(mIsOpen);
if (IsSessionConnectingOrConnected())
if (mIsOpen)
{
TimeMilli now = TimerMilli::GetNow();
mSession->HandleTimer(now);
}
}
void SecureSession::HandleTimer(TimeMilli aNow)
{
if (IsConnectingOrConnected())
{
VerifyOrExit(mTimerSet);
if (aNow < mTimerFinish)
{
mTransport.mTimer.FireAtIfEarlier(mTimerFinish);
ExitNow();
}
Process();
ExitNow();
}
if (IsSessionDisconnecting())
if (IsDisconnecting())
{
if ((mMaxConnectionAttempts > 0) && (mRemainingConnectionAttempts == 0))
if (aNow < mTimerFinish)
{
Close();
mTransport.mTimer.FireAtIfEarlier(mTimerFinish);
ExitNow();
}
if (mTransport.HasNoRemainingConnectionAttempts())
{
mTransport.Close();
mConnectEvent = kDisconnectedMaxAttempts;
mAutoCloseCallback.InvokeIfSet();
mTransport.mAutoCloseCallback.InvokeIfSet();
}
else
{
SetSessionState(kSessionDisconnected);
mTimer.Stop();
SetState(kStateDisconnected);
}
mConnectedCallback.InvokeIfSet(mConnectEvent);
@@ -767,22 +822,22 @@ exit:
return;
}
void SecureTransport::Process(void)
void SecureSession::Process(void)
{
uint8_t buf[kMaxContentLen];
int rval;
ConnectEvent disconnectEvent;
bool shouldReset;
while (IsSessionConnectingOrConnected())
while (IsConnectingOrConnected())
{
if (IsSessionConnecting())
if (IsConnecting())
{
rval = mbedtls_ssl_handshake(&mSsl);
if (IsMbedtlsHandshakeOver(&mSsl))
{
SetSessionState(kSessionConnected);
SetState(kStateConnected);
mConnectEvent = kConnected;
mConnectedCallback.InvokeIfSet(mConnectEvent);
}
@@ -851,9 +906,9 @@ void SecureTransport::Process(void)
{
mbedtls_ssl_session_reset(&mSsl);
if (mCipherSuite == kEcjpakeWithAes128Ccm8)
if (mTransport.mCipherSuite == SecureTransport::kEcjpakeWithAes128Ccm8)
{
mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mTransport.mPsk, mTransport.mPskLength);
}
}
@@ -899,27 +954,27 @@ void SecureTransport::HandleMbedtlsDebug(int aLevel, const char *aFile, int aLin
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
const char *SecureTransport::SessionStateToString(SessionState aState)
const char *SecureSession::StateToString(State aState)
{
static const char *const kSessionStrings[] = {
"Disconnected", // (0) kSessionDisconnected
"Initializing", // (1) kSessionInitializing
"Connecting", // (2) kSessionConnecting
"Connected", // (3) kSessionConnected
"Disconnecting", // (4) kSessionDisconnecting
static const char *const kStateStrings[] = {
"Disconnected", // (0) kStateDisconnected
"Initializing", // (1) kStateInitializing
"Connecting", // (2) kStateConnecting
"Connected", // (3) kStateConnected
"Disconnecting", // (4) kStateDisconnecting
};
struct EnumCheck
{
InitEnumValidatorCounter();
ValidateNextEnum(kSessionDisconnected);
ValidateNextEnum(kSessionInitializing);
ValidateNextEnum(kSessionConnecting);
ValidateNextEnum(kSessionConnected);
ValidateNextEnum(kSessionDisconnecting);
ValidateNextEnum(kStateDisconnected);
ValidateNextEnum(kStateInitializing);
ValidateNextEnum(kStateConnecting);
ValidateNextEnum(kStateConnected);
ValidateNextEnum(kStateDisconnecting);
};
return kSessionStrings[aState];
return kStateStrings[aState];
}
#endif
@@ -929,7 +984,7 @@ const char *SecureTransport::SessionStateToString(SessionState aState)
#if OPENTHREAD_CONFIG_TLS_API_ENABLE
int SecureTransport::Extension::SetApplicationSecureKeys(void)
int SecureTransport::Extension::SetApplicationSecureKeys(mbedtls_ssl_config &aConfig)
{
int rval = 0;
@@ -942,14 +997,14 @@ int SecureTransport::Extension::SetApplicationSecureKeys(void)
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
case kEcdheEcdsaWithAes128Ccm8:
case kEcdheEcdsaWithAes128GcmSha256:
rval = mEcdheEcdsaInfo.SetSecureKeys(mSecureTransport.mConf);
rval = mEcdheEcdsaInfo.SetSecureKeys(aConfig);
VerifyOrExit(rval == 0);
break;
#endif
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
case kPskWithAes128Ccm8:
rval = mPskInfo.SetSecureKeys(mSecureTransport.mConf);
rval = mPskInfo.SetSecureKeys(aConfig);
VerifyOrExit(rval == 0);
break;
#endif
@@ -1079,27 +1134,25 @@ Error SecureTransport::Extension::GetPeerCertificateBase64(unsigned char *aPeerC
size_t *aCertLength,
size_t aCertBufferSize)
{
Error error = kErrorNone;
Error error = kErrorNone;
SecureSession *session = mSecureTransport.mSession;
VerifyOrExit(mSecureTransport.IsSessionConnected(), error = kErrorInvalidState);
VerifyOrExit(session->IsConnected(), error = kErrorInvalidState);
#if (MBEDTLS_VERSION_NUMBER >= 0x03010000)
VerifyOrExit(
mbedtls_base64_encode(aPeerCert, aCertBufferSize, aCertLength,
mSecureTransport.mSsl.MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(peer_cert)->raw.p,
mSecureTransport.mSsl.MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(peer_cert)->raw.len) == 0,
error = kErrorNoBufs);
#else
VerifyOrExit(mbedtls_base64_encode(aPeerCert, aCertBufferSize, aCertLength,
mSecureTransport.mSsl.MBEDTLS_PRIVATE(session)
->MBEDTLS_PRIVATE(peer_cert)
->MBEDTLS_PRIVATE(raw)
.MBEDTLS_PRIVATE(p),
mSecureTransport.mSsl.MBEDTLS_PRIVATE(session)
->MBEDTLS_PRIVATE(peer_cert)
->MBEDTLS_PRIVATE(raw)
.MBEDTLS_PRIVATE(len)) == 0,
session->mSsl.MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(peer_cert)->raw.p,
session->mSsl.MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(peer_cert)->raw.len) ==
0,
error = kErrorNoBufs);
#else
VerifyOrExit(
mbedtls_base64_encode(
aPeerCert, aCertBufferSize, aCertLength,
session->mSsl.MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(peer_cert)->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p),
session->mSsl.MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(peer_cert)->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(
len)) == 0,
error = kErrorNoBufs);
#endif
exit:
@@ -1118,7 +1171,8 @@ Error SecureTransport::Extension::GetPeerSubjectAttributeByOid(const char *aOid,
const mbedtls_asn1_named_data *data;
size_t length;
size_t attributeBufferSize;
mbedtls_x509_crt *peerCert = const_cast<mbedtls_x509_crt *>(mbedtls_ssl_get_peer_cert(&mSecureTransport.mSsl));
SecureSession *session = mSecureTransport.mSession;
mbedtls_x509_crt *peerCert = const_cast<mbedtls_x509_crt *>(mbedtls_ssl_get_peer_cert(&session->mSsl));
VerifyOrExit(aAttributeLength != nullptr, error = kErrorInvalidArgs);
attributeBufferSize = *aAttributeLength;
@@ -1149,7 +1203,7 @@ Error SecureTransport::Extension::GetThreadAttributeFromPeerCertificate(int
uint8_t *aAttributeBuffer,
size_t *aAttributeLength)
{
const mbedtls_x509_crt *cert = mbedtls_ssl_get_peer_cert(&mSecureTransport.mSsl);
const mbedtls_x509_crt *cert = mbedtls_ssl_get_peer_cert(&mSecureTransport.mSession->mSsl);
return GetThreadAttributeFromCertificate(cert, aThreadOidDescriptor, aAttributeBuffer, aAttributeLength);
}
+191 -132
View File
@@ -77,6 +77,7 @@
#include "common/locator.hpp"
#include "common/log.hpp"
#include "common/message.hpp"
#include "common/non_copyable.hpp"
#include "common/random.hpp"
#include "common/timer.hpp"
#include "crypto/sha256.hpp"
@@ -88,11 +89,23 @@ namespace ot {
namespace MeshCoP {
class SecureTransport;
class Dtls;
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
class Tls;
#endif
/**
* Represents a secure transport, used as base class for `Dtls` and `Tls`.
* Represents a secure session.
*/
class SecureTransport : public InstanceLocator
class SecureSession : private NonCopyable
{
friend class SecureTransport;
friend class Dtls;
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
friend class Tls;
#endif
public:
typedef otCoapSecureConnectEvent ConnectEvent; ///< A connect event.
@@ -102,10 +115,9 @@ public:
static constexpr ConnectEvent kDisconnectedMaxAttempts = OT_COAP_SECURE_DISCONNECTED_MAX_ATTEMPTS;
static constexpr ConnectEvent kDisconnectedError = OT_COAP_SECURE_DISCONNECTED_ERROR;
static constexpr uint8_t kPskMaxLength = 32; ///< Maximum PSK length.
/**
* Function pointer which is called reporting a connection event (when connection established or disconnected)
* Function pointer which is called reporting a session connection event (when connection established or
* disconnected).
*/
typedef otHandleCoapSecureClientConnect ConnectedHandler;
@@ -119,7 +131,158 @@ public:
typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength);
/**
* Pointer is called when secure CoAP server want to send encrypted message.
* Sets the connection event callback.
*
* @param[in] aConnectedHandler A pointer to a function that is called when connected or disconnected.
* @param[in] aContext A pointer to arbitrary context information.
*/
void SetConnectedCallback(ConnectedHandler aConnectedHandler, void *aContext)
{
mConnectedCallback.Set(aConnectedHandler, aContext);
}
/**
* Sets the receive callback.
*
* @param[in] aReceiveHandler A pointer to a function that is called to receive payload.
* @param[in] aContext A pointer to arbitrary context information.
*/
void SetReceiveCallback(ReceiveHandler aReceiveHandler, void *aContext)
{
mReceiveCallback.Set(aReceiveHandler, aContext);
}
/**
* Establishes a secure session (as client).
*
* @param[in] aSockAddr The server address to connect to.
*
* @retval kErrorNone Successfully started session establishment
* @retval kErrorInvalidState Transport is not ready.
*/
Error Connect(const Ip6::SockAddr &aSockAddr);
/**
* Disconnects the session.
*/
void Disconnect(void) { Disconnect(kDisconnectedLocalClosed); }
/**
* Sends message to the secure session.
*
* When successful (returning `kErrorNone`), this method takes over the ownership of @p aMessage and will free
* it after transmission. Otherwise, the caller keeps the ownership of @p aMessage.
*
* @param[in] aMessage A message to send.
*
* @retval kErrorNone Successfully sent the message.
* @retval kErrorNoBufs @p aMessage is too long.
*/
Error Send(Message &aMessage);
/**
* Returns the session's peer address.
*
* @return The session's message info.
*/
const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
/**
* Indicates whether or not the session is active (connected, connecting, or disconnecting).
*
* @retval TRUE If session is active.
* @retval FALSE If session is not active.
*/
bool IsConnectionActive(void) const { return (mState != kStateDisconnected); }
/**
* Indicates whether or not the session is connected.
*
* @retval TRUE The session is connected.
* @retval FALSE The session is not connected.
*/
bool IsConnected(void) const { return (mState == kStateConnected); }
private:
static constexpr uint32_t kGuardTimeNewConnectionMilli = 2000;
static constexpr uint16_t kMaxContentLen = OPENTHREAD_CONFIG_DTLS_MAX_CONTENT_LEN;
#if !OPENTHREAD_CONFIG_TLS_API_ENABLE
static constexpr uint16_t kApplicationDataMaxLength = 1152;
#else
static constexpr uint16_t kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH;
#endif
enum State : uint8_t
{
kStateDisconnected,
kStateInitializing,
kStateConnecting,
kStateConnected,
kStateDisconnecting,
};
explicit SecureSession(SecureTransport &aTransport);
bool IsDisconnected(void) const { return mState == kStateDisconnected; }
bool IsInitializing(void) const { return mState == kStateInitializing; }
bool IsConnecting(void) const { return mState == kStateConnecting; }
bool IsDisconnecting(void) const { return mState == kStateDisconnecting; }
bool IsConnectingOrConnected(void) const { return mState == kStateConnecting || mState == kStateConnected; }
void SetState(State aState);
bool Matches(const Ip6::MessageInfo &aInfo) { return mMessageInfo.HasSamePeerAddrAndPort(aInfo); }
void HandleTransportReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
Error Setup(void);
void Disconnect(ConnectEvent aEvent);
void HandleTimer(TimeMilli aNow);
void Process(void);
void FreeMbedtls(void);
static int HandleMbedtlsGetTimer(void *aContext);
int HandleMbedtlsGetTimer(void);
static void HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish);
void HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish);
static int HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength);
int HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength);
static int HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength);
int HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength);
static bool IsMbedtlsHandshakeOver(mbedtls_ssl_context *aSslContext);
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
static const char *StateToString(State aState);
#endif
bool mTimerSet : 1;
State mState;
Message::SubType mMessageSubType;
ConnectEvent mConnectEvent;
TimeMilli mTimerIntermediate;
TimeMilli mTimerFinish;
SecureTransport &mTransport;
Message *mReceiveMessage;
Ip6::MessageInfo mMessageInfo;
Callback<ConnectedHandler> mConnectedCallback;
Callback<ReceiveHandler> mReceiveCallback;
mbedtls_ssl_config mConf;
mbedtls_ssl_context mSsl;
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
mbedtls_ssl_cookie_ctx mCookieCtx;
#endif
};
/**
* Represents a secure transport, used as base class for `Dtls` and `Tls`.
*/
class SecureTransport : public InstanceLocator
{
friend class SecureSession;
public:
static constexpr uint8_t kPskMaxLength = 32; ///< Maximum PSK length.
/**
* Pointer is called to send encrypted message.
*
* @param[in] aContext A pointer to arbitrary context information.
* @param[in] aMessage A reference to the message to send.
@@ -150,6 +313,7 @@ public:
class Extension
{
friend SecureTransport;
friend SecureSession;
public:
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
@@ -347,7 +511,7 @@ public:
};
#endif
int SetApplicationSecureKeys(void);
int SetApplicationSecureKeys(mbedtls_ssl_config &aConfig);
Error GetThreadAttributeFromCertificate(const mbedtls_x509_crt *aCert,
int aThreadOidDescriptor,
uint8_t *aAttributeBuffer,
@@ -373,7 +537,9 @@ public:
* @retval kErrorNone Successfully opened the socket.
* @retval kErrorAlready The connection is already open.
*/
Error Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext);
Error Open(SecureSession::ReceiveHandler aReceiveHandler,
SecureSession::ConnectedHandler aConnectedHandler,
void *aContext);
/**
* Sets the maximum number of allowed connection requests before socket is automatically closed.
@@ -422,36 +588,6 @@ public:
*/
Error Bind(TransportCallback aCallback, void *aContext);
/**
* Establishes a secure session.
*
* For CoAP Secure API do first:
* Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or
* set PreShared Key for use DTLS mode PSK with AES 128 CCM 8.
*
* @param[in] aSockAddr A reference to the remote sockaddr.
*
* @retval kErrorNone Successfully started handshake.
* @retval kErrorInvalidState The socket is not open.
*/
Error Connect(const Ip6::SockAddr &aSockAddr);
/**
* Indicates whether or not the session is active.
*
* @retval TRUE If session is active.
* @retval FALSE If session is not active.
*/
bool IsConnectionActive(void) const { return mSessionState >= kSessionConnecting; }
/**
* Indicates whether or not the session is connected.
*
* @retval TRUE The session is connected.
* @retval FALSE The session is not connected.
*/
bool IsConnected(void) const { return mSessionState == kSessionConnected; }
/**
* Indicates whether or not the secure transpose socket is closed.
*
@@ -460,11 +596,6 @@ public:
*/
bool IsClosed(void) const { return !mIsOpen; }
/**
* Disconnects the session.
*/
void Disconnect(void) { Disconnect(kDisconnectedLocalClosed); }
/**
* Closes the socket.
*/
@@ -480,26 +611,6 @@ public:
*/
Error SetPsk(const uint8_t *aPsk, uint8_t aPskLength);
/**
* Sends message to the secure session.
*
* When successful (returning `kErrorNone`), this method takes over the ownership of @p aMessage and will free it
* after transmission. Otherwise, the caller keeps the ownership of @p aMessage.
*
* @param[in] aMessage A message to send.
*
* @retval kErrorNone Successfully sent the message.
* @retval kErrorNoBufs @p aMessage is too long.
*/
Error Send(Message &aMessage);
/**
* Returns the session's peer address.
*
* @return session's message info.
*/
const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
/**
* Checks and handles a received message provided to the SecureTransport object. If checks based on
* the message info and current connection state pass, the message is processed.
@@ -512,29 +623,15 @@ public:
protected:
SecureTransport(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity, bool aDatagramTransport);
void SetSession(SecureSession &aSesssion) { mSession = &aSesssion; }
#if OPENTHREAD_CONFIG_TLS_API_ENABLE
void SetExtension(Extension &aExtension) { mExtension = &aExtension; }
#endif
private:
static constexpr uint16_t kMaxContentLen = OPENTHREAD_CONFIG_DTLS_MAX_CONTENT_LEN;
static constexpr uint32_t kGuardTimeNewConnectionMilli = 2000;
static constexpr size_t kSecureTransportKeyBlockSize = 40;
static constexpr size_t kSecureTransportRandomBufferSize = 32;
#if !OPENTHREAD_CONFIG_TLS_API_ENABLE
static constexpr uint16_t kApplicationDataMaxLength = 1152;
#else
static constexpr uint16_t kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH;
#endif
enum SessionState : uint8_t
{
kSessionDisconnected,
kSessionInitializing,
kSessionConnecting,
kSessionConnected,
kSessionDisconnecting,
};
static constexpr size_t kSecureTransportKeyBlockSize = 40;
static constexpr size_t kSecureTransportRandomBufferSize = 32;
enum CipherSuite : uint8_t
{
@@ -549,37 +646,16 @@ private:
kUnspecifiedCipherSuite,
};
bool IsSessionDisconnected(void) const { return mSessionState == kSessionDisconnected; }
bool IsSessionInitializing(void) const { return mSessionState == kSessionInitializing; }
bool IsSessionConnecting(void) const { return mSessionState == kSessionConnecting; }
bool IsSessionConnected(void) const { return mSessionState == kSessionConnected; }
bool IsSessionDisconnecting(void) const { return mSessionState == kSessionDisconnecting; }
bool IsSessionConnectingOrConnected(void) const
{
return mSessionState == kSessionConnecting || mSessionState == kSessionConnected;
}
void SetSessionState(SessionState aSessionState);
void FreeMbedtls(void);
Error Setup(void);
static bool IsMbedtlsHandshakeOver(mbedtls_ssl_context *aSslContext);
void DecremenetRemainingConnectionAttempts(void);
bool HasNoRemainingConnectionAttempts(void) const;
int Transmit(const unsigned char *aBuf,
size_t aLength,
const Ip6::MessageInfo &aMessageInfo,
Message::SubType aMessageSubType);
static void HandleMbedtlsDebug(void *aContext, int aLevel, const char *aFile, int aLine, const char *aStr);
void HandleMbedtlsDebug(int aLevel, const char *aFile, int aLine, const char *aStr);
static int HandleMbedtlsGetTimer(void *aContext);
int HandleMbedtlsGetTimer(void);
static void HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish);
void HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish);
static int HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength);
int HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength);
static int HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength);
int HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength);
#ifdef MBEDTLS_SSL_EXPORT_KEYS
#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
@@ -618,13 +694,6 @@ private:
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
void Process(void);
void Disconnect(ConnectEvent aEvent);
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
static const char *SessionStateToString(SessionState aState);
#endif
using TransportSocket = Ip6::Udp::SocketIn<SecureTransport, &SecureTransport::HandleReceive>;
#if (MBEDTLS_VERSION_NUMBER >= 0x03010000)
@@ -647,31 +716,17 @@ private:
bool mDatagramTransport : 1;
bool mIsOpen : 1;
bool mIsServer : 1;
bool mTimerSet : 1;
bool mVerifyPeerCertificate : 1;
SessionState mSessionState;
CipherSuite mCipherSuite;
Message::SubType mMessageSubType;
ConnectEvent mConnectEvent;
uint8_t mPskLength;
uint16_t mMaxConnectionAttempts;
uint16_t mRemainingConnectionAttempts;
Message *mReceiveMessage;
Ip6::MessageInfo mMessageInfo;
SecureSession *mSession;
TransportSocket mSocket;
uint8_t mPsk[kPskMaxLength];
TimeMilli mTimerIntermediate;
TimeMilli mTimerFinish;
TimerMilliContext mTimer;
Callback<AutoCloseCallback> mAutoCloseCallback;
Callback<ConnectedHandler> mConnectedCallback;
Callback<ReceiveHandler> mReceiveCallback;
Callback<TransportCallback> mTransportCallback;
mbedtls_ssl_context mSsl;
mbedtls_ssl_config mConf;
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_COOKIE_C)
mbedtls_ssl_cookie_ctx mCookieCtx;
#endif
#if OPENTHREAD_CONFIG_TLS_API_ENABLE
Extension *mExtension;
#endif
@@ -680,7 +735,7 @@ private:
/**
* Represents a DTLS instance.
*/
class Dtls : public SecureTransport
class Dtls : public SecureTransport, public SecureSession
{
public:
/**
@@ -691,7 +746,9 @@ public:
*/
Dtls(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity)
: SecureTransport(aInstance, aLayerTwoSecurity, /* aDatagramTransport */ true)
, SecureSession(*static_cast<SecureTransport *>(this))
{
SetSession(*static_cast<SecureSession *>(this));
}
};
@@ -724,7 +781,7 @@ public:
/**
* Represents a TLS instance.
*/
class Tls : public SecureTransport
class Tls : public SecureTransport, public SecureSession
{
public:
/**
@@ -736,7 +793,9 @@ public:
*/
Tls(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity, Extension &aExtension)
: SecureTransport(aInstance, aLayerTwoSecurity, /* aDatagramTransport */ false)
, SecureSession(*static_cast<SecureTransport *>(this))
{
SetSession(*static_cast<SecureSession *>(this));
SetExtension(aExtension);
}
};