From 2e395771113477fb159892a1409a0f15ae3d3aa0 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 26 Dec 2024 12:40:08 -0800 Subject: [PATCH] [coaps] introduce `Coap::SecureSession` along with `Dtls::Transport` (#11056) This commit introduces the `Dtls::Transport` and `Dtls::Session` classes, separating session-related functions from transport-related behaviors. It also introduces the `Coap::SecureSession` class, which handles CoAP processing over a DTLS session. This simplifies the code by allowing `Coap::SecureSession` to inherit many of its methods from `Dtls::Session`, avoiding repetition. It also separates CoAP-specific message processing from transport-related functionality. `Tmf::SecureAgent` and `ApplicationCoapSecure` are updated to act as both a `Dtls::Transport` and a single `Coap::SecureSession`. --- src/core/api/coap_secure_api.cpp | 30 ++- src/core/coap/coap_secure.cpp | 169 +++++------------ src/core/coap/coap_secure.hpp | 261 ++++---------------------- src/core/meshcop/border_agent.cpp | 34 ++-- src/core/meshcop/border_agent.hpp | 7 +- src/core/meshcop/commissioner.cpp | 27 ++- src/core/meshcop/commissioner.hpp | 4 +- src/core/meshcop/joiner.cpp | 11 +- src/core/meshcop/joiner.hpp | 4 +- src/core/meshcop/meshcop.hpp | 7 + src/core/meshcop/secure_transport.cpp | 14 +- src/core/meshcop/secure_transport.hpp | 95 ++++++---- src/core/thread/thread_netif.cpp | 2 +- src/core/thread/tmf.cpp | 4 +- src/core/thread/tmf.hpp | 4 +- tests/nexus/test_dtls.cpp | 69 ++++--- 16 files changed, 271 insertions(+), 471 deletions(-) diff --git a/src/core/api/coap_secure_api.cpp b/src/core/api/coap_secure_api.cpp index ec4369889..59e3bbff8 100644 --- a/src/core/api/coap_secure_api.cpp +++ b/src/core/api/coap_secure_api.cpp @@ -41,7 +41,13 @@ using namespace ot; otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort) { - return AsCoreType(aInstance).GetApplicationCoapSecure().Start(aPort); + otError error; + + SuccessOrExit(error = AsCoreType(aInstance).GetApplicationCoapSecure().Open()); + error = AsCoreType(aInstance).GetApplicationCoapSecure().Bind(aPort); + +exit: + return error; } otError otCoapSecureStartWithMaxConnAttempts(otInstance *aInstance, @@ -50,7 +56,14 @@ otError otCoapSecureStartWithMaxConnAttempts(otInstance *aInsta otCoapSecureAutoStopCallback aCallback, void *aContext) { - return AsCoreType(aInstance).GetApplicationCoapSecure().Start(aPort, aMaxAttempts, aCallback, aContext); + Error error = kErrorAlready; + + SuccessOrExit( + AsCoreType(aInstance).GetApplicationCoapSecure().SetMaxConnectionAttempts(aMaxAttempts, aCallback, aContext)); + error = otCoapSecureStart(aInstance, aPort); + +exit: + return error; } #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED @@ -129,7 +142,7 @@ bool otCoapSecureIsConnectionActive(otInstance *aInstance) bool otCoapSecureIsClosed(otInstance *aInstance) { return AsCoreType(aInstance).GetApplicationCoapSecure().IsClosed(); } -void otCoapSecureStop(otInstance *aInstance) { AsCoreType(aInstance).GetApplicationCoapSecure().Stop(); } +void otCoapSecureStop(otInstance *aInstance) { AsCoreType(aInstance).GetApplicationCoapSecure().Close(); } #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE otError otCoapSecureSendRequestBlockWise(otInstance *aInstance, @@ -193,15 +206,18 @@ otError otCoapSecureSendResponseBlockWise(otInstance *aInstance, void *aContext, otCoapBlockwiseTransmitHook aTransmitHook) { - return AsCoreType(aInstance).GetApplicationCoapSecure().SendMessage( - AsCoapMessage(aMessage), AsCoreType(aMessageInfo), nullptr, aContext, aTransmitHook); + OT_UNUSED_VARIABLE(aMessageInfo); + + return AsCoreType(aInstance).GetApplicationCoapSecure().SendMessage(AsCoapMessage(aMessage), nullptr, aContext, + aTransmitHook); } #endif otError otCoapSecureSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo) { - return AsCoreType(aInstance).GetApplicationCoapSecure().SendMessage(AsCoapMessage(aMessage), - AsCoreType(aMessageInfo)); + OT_UNUSED_VARIABLE(aMessageInfo); + + return AsCoreType(aInstance).GetApplicationCoapSecure().SendMessage(AsCoapMessage(aMessage)); } #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp index 4f66f3f79..91e236dc5 100644 --- a/src/core/coap/coap_secure.cpp +++ b/src/core/coap/coap_secure.cpp @@ -34,7 +34,7 @@ /** * @file - * This file implements the secure CoAP agent. + * This file implements the secure CoAP session. */ namespace ot { @@ -42,164 +42,97 @@ namespace Coap { RegisterLogModule("CoapSecure"); -CoapSecureBase::CoapSecureBase(Instance &aInstance, MeshCoP::Dtls &aDtls) - : CoapBase(aInstance, Send) - , mDtls(aDtls) - , mTransmitTask(aInstance, HandleTransmit, this) +SecureSession::SecureSession(Instance &aInstance, Dtls::Transport &aDtlsTransport) + : CoapBase(aInstance, Transmit) + , Dtls::Session(aDtlsTransport) + , mTransmitTask(aInstance, HandleTransmitTask, this) { -} - -Error CoapSecureBase::Start(uint16_t aPort) { return Start(aPort, /* aMaxAttempts */ 0, nullptr, nullptr); } - -Error CoapSecureBase::Start(uint16_t aPort, uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext) -{ - Error error; - - SuccessOrExit(error = Open(aMaxAttempts, aCallback, aContext)); - error = mDtls.Bind(aPort); - -exit: - return error; -} - -Error CoapSecureBase::Start(MeshCoP::Dtls::TransportCallback aCallback, void *aContext) -{ - Error error; - - SuccessOrExit(error = Open(/* aMaxAttemps */ 0, nullptr, nullptr)); - error = mDtls.Bind(aCallback, aContext); - -exit: - return error; -} - -Error CoapSecureBase::Open(uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext) -{ - Error error = kErrorAlready; - - SuccessOrExit(mDtls.SetMaxConnectionAttempts(aMaxAttempts, HandleDtlsAutoClose, this)); - mAutoStopCallback.Set(aCallback, aContext); - SuccessOrExit(mDtls.Open()); - mDtls.SetReceiveCallback(HandleDtlsReceive, this); - - error = kErrorNone; - -exit: - return error; -} - -void CoapSecureBase::Stop(void) -{ - mDtls.Close(); - - mTransmitQueue.DequeueAndFreeAll(); - ClearRequestsAndResponses(); -} - -void CoapSecureBase::SetPsk(const MeshCoP::JoinerPskd &aPskd) -{ - static_assert(static_cast(MeshCoP::JoinerPskd::kMaxLength) <= - static_cast(MeshCoP::Dtls::kPskMaxLength), - "The maximum length of DTLS PSK is smaller than joiner PSKd"); - - SuccessOrAssert(mDtls.SetPsk(reinterpret_cast(aPskd.GetAsCString()), aPskd.GetLength())); + Dtls::Session::SetConnectCallback(HandleDtlsConnectEvent, this); + Dtls::Session::SetReceiveCallback(HandleDtlsReceive, this); } #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE -Error CoapSecureBase::SendMessage(Message &aMessage, - ResponseHandler aHandler, - void *aContext, - otCoapBlockwiseTransmitHook aTransmitHook, - otCoapBlockwiseReceiveHook aReceiveHook) + +Error SecureSession::SendMessage(Message &aMessage, + ResponseHandler aHandler, + void *aContext, + otCoapBlockwiseTransmitHook aTransmitHook, + otCoapBlockwiseReceiveHook aReceiveHook) { - Error error = kErrorNone; - - VerifyOrExit(IsConnected(), error = kErrorInvalidState); - - error = CoapBase::SendMessage(aMessage, mDtls.GetMessageInfo(), TxParameters::GetDefault(), aHandler, aContext, - aTransmitHook, aReceiveHook); - -exit: - return error; + return IsConnected() ? CoapBase::SendMessage(aMessage, GetMessageInfo(), TxParameters::GetDefault(), aHandler, + aContext, aTransmitHook, aReceiveHook) + : kErrorInvalidState; } -Error CoapSecureBase::SendMessage(Message &aMessage, - const Ip6::MessageInfo &aMessageInfo, - ResponseHandler aHandler, - void *aContext, - otCoapBlockwiseTransmitHook aTransmitHook, - otCoapBlockwiseReceiveHook aReceiveHook) +#else + +Error SecureSession::SendMessage(Message &aMessage, ResponseHandler aHandler, void *aContext) { - return CoapBase::SendMessage(aMessage, aMessageInfo, TxParameters::GetDefault(), aHandler, aContext, aTransmitHook, - aReceiveHook); -} -#else // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE -Error CoapSecureBase::SendMessage(Message &aMessage, ResponseHandler aHandler, void *aContext) -{ - Error error = kErrorNone; - - VerifyOrExit(IsConnected(), error = kErrorInvalidState); - - error = CoapBase::SendMessage(aMessage, mDtls.GetMessageInfo(), aHandler, aContext); - -exit: - return error; + return IsConnected() ? CoapBase::SendMessage(aMessage, GetMessageInfo(), aHandler, aContext) : kErrorInvalidState; } -Error CoapSecureBase::SendMessage(Message &aMessage, - const Ip6::MessageInfo &aMessageInfo, - ResponseHandler aHandler, - void *aContext) -{ - return CoapBase::SendMessage(aMessage, aMessageInfo, aHandler, aContext); -} #endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE -Error CoapSecureBase::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +Error SecureSession::Transmit(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +{ + return static_cast(aCoapBase).Transmit(aMessage, aMessageInfo); +} + +Error SecureSession::Transmit(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { OT_UNUSED_VARIABLE(aMessageInfo); + Error error = kErrorNone; + + VerifyOrExit(!GetTransport().IsClosed(), error = kErrorInvalidState); + mTransmitQueue.Enqueue(aMessage); mTransmitTask.Post(); - return kErrorNone; +exit: + return error; } -void CoapSecureBase::HandleDtlsAutoClose(void *aContext) +void SecureSession::HandleDtlsConnectEvent(ConnectEvent aEvent, void *aContext) { - return static_cast(aContext)->HandleDtlsAutoClose(); + static_cast(aContext)->HandleDtlsConnectEvent(aEvent); } -void CoapSecureBase::HandleDtlsAutoClose(void) +void SecureSession::HandleDtlsConnectEvent(ConnectEvent aEvent) { - Stop(); - mAutoStopCallback.InvokeIfSet(); + if (aEvent != kConnected) + { + mTransmitQueue.DequeueAndFreeAll(); + ClearRequestsAndResponses(); + } + + mConnectCallback.InvokeIfSet(aEvent); } -void CoapSecureBase::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength) +void SecureSession::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength) { - return static_cast(aContext)->HandleDtlsReceive(aBuf, aLength); + static_cast(aContext)->HandleDtlsReceive(aBuf, aLength); } -void CoapSecureBase::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength) +void SecureSession::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength) { ot::Message *message = nullptr; VerifyOrExit((message = Get().Allocate(Message::kTypeIp6, Message::GetHelpDataReserved())) != nullptr); SuccessOrExit(message->AppendBytes(aBuf, aLength)); - CoapBase::Receive(*message, mDtls.GetMessageInfo()); + CoapBase::Receive(*message, GetMessageInfo()); exit: FreeMessage(message); } -void CoapSecureBase::HandleTransmit(Tasklet &aTasklet) +void SecureSession::HandleTransmitTask(Tasklet &aTasklet) { - static_cast(static_cast(aTasklet).GetContext())->HandleTransmit(); + static_cast(static_cast(aTasklet).GetContext())->HandleTransmitTask(); } -void CoapSecureBase::HandleTransmit(void) +void SecureSession::HandleTransmitTask(void) { Error error = kErrorNone; ot::Message *message = mTransmitQueue.GetHead(); @@ -212,12 +145,10 @@ void CoapSecureBase::HandleTransmit(void) mTransmitTask.Post(); } - SuccessOrExit(error = mDtls.Send(*message)); - LogDebg("Transmit"); + error = Dtls::Session::Send(*message); exit: FreeMessageOnError(message, error); - LogWarnOnError(error, "transmit"); } } // namespace Coap diff --git a/src/core/coap/coap_secure.hpp b/src/core/coap/coap_secure.hpp index ba15ee9ae..16bbabd54 100644 --- a/src/core/coap/coap_secure.hpp +++ b/src/core/coap/coap_secure.hpp @@ -46,149 +46,31 @@ /** * @file - * This file includes definitions for the secure CoAP agent. + * This file includes definitions for the secure CoAP. */ namespace ot { - namespace Coap { -class CoapSecureBase : public CoapBase +typedef MeshCoP::Dtls Dtls; + +/** + * Represents a secure CoAP session. + */ +class SecureSession : public CoapBase, public Dtls::Session { public: /** - * Function pointer which is called reporting a connection event (when connection established or disconnected) - */ - typedef MeshCoP::SecureSession::ConnectHandler ConnectHandler; - - /** - * Callback to notify when the agent is automatically stopped due to reaching the maximum number of connection - * attempts. - */ - typedef otCoapSecureAutoStopCallback AutoStopCallback; - - /** - * Starts the secure CoAP agent. + * Sets the connection event callback. * - * @param[in] aPort The local UDP port to bind to. - * - * @retval kErrorNone Successfully started the CoAP agent. - * @retval kErrorAlready Already started. - */ - Error Start(uint16_t aPort); - - /** - * Starts the secure CoAP agent and sets the maximum number of allowed connection attempts before stopping the - * agent automatically. - * - * @param[in] aPort The local UDP port to bind to. - * @param[in] aMaxAttempts Maximum number of allowed connection request attempts. Zero indicates no limit. - * @param[in] aCallback Callback to notify if max number of attempts has reached and agent is stopped. - * @param[in] aContext A pointer to arbitrary context to use with `AutoStopCallback`. - * - * @retval kErrorNone Successfully started the CoAP agent. - * @retval kErrorAlready Already started. - */ - Error Start(uint16_t aPort, uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext); - - /** - * Starts the secure CoAP agent, but do not use socket to transmit/receive messages. - * - * @param[in] aCallback A pointer to a function for sending messages. - * @param[in] aContext A pointer to arbitrary context information. - * - * @retval kErrorNone Successfully started the CoAP agent. - * @retval kErrorAlready Already started. - */ - Error Start(MeshCoP::Dtls::TransportCallback aCallback, void *aContext); - - /** - * Sets connected callback of this secure CoAP agent. - * - * @param[in] aCallback A pointer to a function to get called when connection state changes. + * @param[in] aHandler A pointer to a function that is called when connected or disconnected. * @param[in] aContext A pointer to arbitrary context information. */ - void SetConnectCallback(ConnectHandler aCallback, void *aContext) { mDtls.SetConnectCallback(aCallback, aContext); } - - /** - * Stops the secure CoAP agent. - */ - void Stop(void); - - /** - * Initializes DTLS session with a peer. - * - * @param[in] aSockAddr A reference to the remote socket address, - * - * @retval kErrorNone Successfully started DTLS connection. - * @retval kErrorInvalidState DTLS transport is not ready. - */ - Error Connect(const Ip6::SockAddr &aSockAddr) { return mDtls.Connect(aSockAddr); } - - /** - * Indicates whether or not the DTLS session is active. - * - * @retval TRUE If DTLS session is active. - * @retval FALSE If DTLS session is not active. - */ - bool IsConnectionActive(void) const { return mDtls.IsConnectionActive(); } - - /** - * Indicates whether or not the DTLS session is connected. - * - * @retval TRUE The DTLS session is connected. - * @retval FALSE The DTLS session is not connected. - */ - bool IsConnected(void) const { return mDtls.IsConnected(); } - - /** - * Indicates whether or not the DTLS session is closed. - * - * @retval TRUE The DTLS session is closed - * @retval FALSE The DTLS session is not closed. - */ - bool IsClosed(void) const { return mDtls.IsClosed(); } - - /** - * Stops the DTLS connection. - */ - void Disconnect(void) { mDtls.Disconnect(); } - - /** - * Returns a reference to the DTLS object. - * - * @returns A reference to the DTLS object. - */ - MeshCoP::Dtls &GetDtls(void) { return mDtls; } - - /** - * Gets the UDP port of this agent. - * - * @returns UDP port number. - */ - uint16_t GetUdpPort(void) const { return mDtls.GetUdpPort(); } - - /** - * Sets the PSK. - * - * @param[in] aPsk A pointer to the PSK. - * @param[in] aPskLength The PSK length. - * - * @retval kErrorNone Successfully set the PSK. - * @retval kErrorInvalidArgs The PSK is invalid. - */ - Error SetPsk(const uint8_t *aPsk, uint8_t aPskLength) { return mDtls.SetPsk(aPsk, aPskLength); } - - /** - * Sets the PSK. - * - * @param[in] aPskd A Joiner PSKd. - */ - void SetPsk(const MeshCoP::JoinerPskd &aPskd); + void SetConnectCallback(ConnectHandler aHandler, void *aContext) { mConnectCallback.Set(aHandler, aContext); } #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE /** - * Sends a CoAP message over secure DTLS connection. + * Sends a CoAP message over secure DTLS session. * * If a response for a request is expected, respective function and context information should be provided. * If no response is expected, these arguments should be NULL pointers. @@ -210,33 +92,9 @@ public: otCoapBlockwiseTransmitHook aTransmitHook = nullptr, otCoapBlockwiseReceiveHook aReceiveHook = nullptr); +#else /** - * Sends a CoAP message over secure DTLS connection. - * - * If a response for a request is expected, respective function and context information should be provided. - * If no response is expected, these arguments should be NULL pointers. - * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message. - * - * @param[in] aMessage A reference to the message to send. - * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. - * @param[in] aHandler A function pointer that shall be called on response reception or time-out. - * @param[in] aContext A pointer to arbitrary context information. - * @param[in] aTransmitHook A pointer to a hook function for outgoing block-wise transfer. - * @param[in] aReceiveHook A pointer to a hook function for incoming block-wise transfer. - * - * @retval kErrorNone Successfully sent CoAP message. - * @retval kErrorNoBufs Failed to allocate retransmission data. - * @retval kErrorInvalidState DTLS connection was not initialized. - */ - Error SendMessage(Message &aMessage, - const Ip6::MessageInfo &aMessageInfo, - ResponseHandler aHandler = nullptr, - void *aContext = nullptr, - otCoapBlockwiseTransmitHook aTransmitHook = nullptr, - otCoapBlockwiseReceiveHook aReceiveHook = nullptr); -#else // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE - /** - * Sends a CoAP message over secure DTLS connection. + * Sends a CoAP message over secure DTLS session. * * If a response for a request is expected, respective function and context information should be provided. * If no response is expected, these arguments should be nullptr pointers. @@ -251,75 +109,24 @@ public: * @retval kErrorInvalidState DTLS connection was not initialized. */ Error SendMessage(Message &aMessage, ResponseHandler aHandler = nullptr, void *aContext = nullptr); - - /** - * Sends a CoAP message over secure DTLS connection. - * - * If a response for a request is expected, respective function and context information should be provided. - * If no response is expected, these arguments should be nullptr pointers. - * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message. - * - * @param[in] aMessage A reference to the message to send. - * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. - * @param[in] aHandler A function pointer that shall be called on response reception or time-out. - * @param[in] aContext A pointer to arbitrary context information. - * - * @retval kErrorNone Successfully sent CoAP message. - * @retval kErrorNoBufs Failed to allocate retransmission data. - * @retval kErrorInvalidState DTLS connection was not initialized. - */ - Error SendMessage(Message &aMessage, - const Ip6::MessageInfo &aMessageInfo, - ResponseHandler aHandler = nullptr, - void *aContext = nullptr); -#endif // OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE - - /** - * Is used to pass UDP messages to the secure CoAP server. - * - * @param[in] aMessage A reference to the received message. - * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. - */ - void HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) - { - return mDtls.HandleReceive(aMessage, aMessageInfo); - } - - /** - * Returns the DTLS session's peer address. - * - * @return DTLS session's message info. - */ - const Ip6::MessageInfo &GetMessageInfo(void) const { return mDtls.GetMessageInfo(); } +#endif protected: - CoapSecureBase(Instance &aInstance, MeshCoP::Dtls &aDtls); + SecureSession(Instance &aInstance, Dtls::Transport &aDtlsTransport); - Error Open(uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext); +private: + static Error Transmit(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + Error Transmit(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + static void HandleTransmitTask(Tasklet &aTasklet); + void HandleTransmitTask(void); + static void HandleDtlsConnectEvent(ConnectEvent aEvent, void *aContext); + void HandleDtlsConnectEvent(ConnectEvent aEvent); + static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength); + void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength); - static Error Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) - { - return static_cast(aCoapBase).Send(aMessage, aMessageInfo); - } - - Error Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - - static void HandleDtlsConnectEvent(MeshCoP::Dtls::ConnectEvent aEvent, void *aContext); - void HandleDtlsConnectEvent(MeshCoP::Dtls::ConnectEvent aEvent); - - static void HandleDtlsAutoClose(void *aContext); - void HandleDtlsAutoClose(void); - - static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength); - void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength); - - static void HandleTransmit(Tasklet &aTasklet); - void HandleTransmit(void); - - MeshCoP::Dtls &mDtls; - Callback mAutoStopCallback; - ot::MessageQueue mTransmitQueue; - TaskletContext mTransmitTask; + Callback mConnectCallback; + ot::MessageQueue mTransmitQueue; + TaskletContext mTransmitTask; }; #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE @@ -327,24 +134,22 @@ protected: /** * Represents an Application CoAPS. */ -class ApplicationCoapSecure : public CoapSecureBase, public MeshCoP::Dtls::Extension +class ApplicationCoapSecure : public Dtls::Transport, public Dtls::Transport::Extension, public SecureSession { public: /** - * Initializes the object. + * Initializes the `ApplicationCoapSecure` * * @param[in] aInstance A reference to the OpenThread instance. * @param[in] aLayerTwoSecurity Specifies whether to use layer two security or not. */ ApplicationCoapSecure(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity) - : CoapSecureBase(aInstance, mDtls) - , MeshCoP::Dtls::Extension(mDtls) - , mDtls(aInstance, aLayerTwoSecurity, *this) + : Dtls::Transport(aInstance, aLayerTwoSecurity) + , Dtls::Transport::Extension(static_cast(*this)) + , SecureSession(aInstance, static_cast(*this)) { + Dtls::Transport::SetExtension(static_cast(*this)); } - -private: - MeshCoP::DtlsExtended mDtls; }; #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp index a8a143b0c..8b926297a 100644 --- a/src/core/meshcop/border_agent.cpp +++ b/src/core/meshcop/border_agent.cpp @@ -123,14 +123,13 @@ Error BorderAgent::Start(uint16_t aUdpPort, const uint8_t *aPsk, uint8_t aPskLen #if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE if (mUsingEphemeralKey) { - SuccessOrExit(error = Get().Start(aUdpPort, kMaxEphemeralKeyConnectionAttempts, - HandleSecureAgentStopped, this)); + SuccessOrExit(error = Get().SetMaxConnectionAttempts(kMaxEphemeralKeyConnectionAttempts, + HandleSecureAgentStopped, this)); } - else #endif - { - SuccessOrExit(error = Get().Start(aUdpPort)); - } + + SuccessOrExit(error = Get().Open()); + SuccessOrExit(error = Get().Bind(aUdpPort)); SuccessOrExit(error = Get().SetPsk(aPsk, aPskLength)); @@ -160,7 +159,7 @@ void BorderAgent::Stop(void) #endif mTimer.Stop(); - Get().Stop(); + Get().Close(); mState = kStateStopped; mUdpProxyPort = 0; @@ -234,14 +233,14 @@ void BorderAgent::HandleTimeout(void) } } -void BorderAgent::HandleConnected(Dtls::ConnectEvent aEvent, void *aContext) +void BorderAgent::HandleConnected(Dtls::Session::ConnectEvent aEvent, void *aContext) { static_cast(aContext)->HandleConnected(aEvent); } -void BorderAgent::HandleConnected(Dtls::ConnectEvent aEvent) +void BorderAgent::HandleConnected(Dtls::Session::ConnectEvent aEvent) { - if (aEvent == Dtls::kConnected) + if (aEvent == Dtls::Session::kConnected) { LogInfo("SecureSession connected"); mState = kStateConnected; @@ -269,11 +268,11 @@ void BorderAgent::HandleConnected(Dtls::ConnectEvent aEvent) { RestartAfterRemovingEphemeralKey(); - if (aEvent == Dtls::kDisconnectedError) + if (aEvent == Dtls::Session::kDisconnectedError) { mCounters.mEpskcSecureSessionFailures++; } - else if (aEvent == Dtls::kDisconnectedPeerClosed) + else if (aEvent == Dtls::Session::kDisconnectedPeerClosed) { mCounters.mEpskcDeactivationDisconnects++; } @@ -284,7 +283,7 @@ void BorderAgent::HandleConnected(Dtls::ConnectEvent aEvent) mState = kStateStarted; mUdpProxyPort = 0; - if (aEvent == Dtls::kDisconnectedError) + if (aEvent == Dtls::Session::kDisconnectedError) { mCounters.mPskcSecureSessionFailures++; } @@ -520,10 +519,7 @@ exit: return error; } -Error BorderAgent::SendMessage(Coap::Message &aMessage) -{ - return Get().SendMessage(aMessage, Get().GetMessageInfo()); -} +Error BorderAgent::SendMessage(Coap::Message &aMessage) { return Get().SendMessage(aMessage); } void BorderAgent::SendErrorMessage(const ForwardContext &aForwardContext, Error aError) { @@ -706,6 +702,8 @@ exit: void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Uri aUri) { + OT_UNUSED_VARIABLE(aMessageInfo); + Error error = kErrorNone; Coap::Message *response = nullptr; @@ -733,7 +731,7 @@ void BorderAgent::HandleTmfDatasetGet(Coap::Message &aMessage, const Ip6::Messag VerifyOrExit(response != nullptr, error = kErrorParse); - SuccessOrExit(error = Get().SendMessage(*response, aMessageInfo)); + SuccessOrExit(error = Get().SendMessage(*response)); LogInfo("Sent %s response to non-active commissioner", PathForUri(aUri)); diff --git a/src/core/meshcop/border_agent.hpp b/src/core/meshcop/border_agent.hpp index a6b5f373e..e5de00b63 100644 --- a/src/core/meshcop/border_agent.hpp +++ b/src/core/meshcop/border_agent.hpp @@ -256,7 +256,8 @@ public: uint16_t GetUdpProxyPort(void) const { return mUdpProxyPort; } private: - static_assert(kMaxEphemeralKeyLength <= Dtls::kPskMaxLength, "Max ephemeral key length is larger than max PSK len"); + static_assert(kMaxEphemeralKeyLength <= Dtls::Transport::kPskMaxLength, + "Max ephemeral key length is larger than max PSK len"); static constexpr uint16_t kUdpPort = OPENTHREAD_CONFIG_BORDER_AGENT_UDP_PORT; static constexpr uint32_t kKeepAliveTimeout = 50 * 1000; // Timeout to reject a commissioner (in msec) @@ -295,8 +296,8 @@ private: template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - static void HandleConnected(Dtls::ConnectEvent aEvent, void *aContext); - void HandleConnected(Dtls::ConnectEvent aEvent); + static void HandleConnected(Dtls::Session::ConnectEvent aEvent, void *aContext); + void HandleConnected(Dtls::Session::ConnectEvent aEvent); static void HandleCoapResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp index 9c9440e9b..e58d7cf02 100644 --- a/src/core/meshcop/commissioner.cpp +++ b/src/core/meshcop/commissioner.cpp @@ -112,14 +112,14 @@ exit: return; } -void Commissioner::HandleSecureAgentConnectEvent(Dtls::ConnectEvent aEvent, void *aContext) +void Commissioner::HandleSecureAgentConnectEvent(Dtls::Session::ConnectEvent aEvent, void *aContext) { static_cast(aContext)->HandleSecureAgentConnectEvent(aEvent); } -void Commissioner::HandleSecureAgentConnectEvent(Dtls::ConnectEvent aEvent) +void Commissioner::HandleSecureAgentConnectEvent(Dtls::Session::ConnectEvent aEvent) { - bool isConnected = (aEvent == Dtls::kConnected); + bool isConnected = (aEvent == Dtls::Session::kConnected); if (!isConnected) { mJoinerSessionTimer.Stop(); @@ -272,7 +272,9 @@ Error Commissioner::Start(StateCallback aStateCallback, JoinerCallback aJoinerCa Get().Stop(); #endif - SuccessOrExit(error = Get().Start(SendRelayTransmit, this)); + SuccessOrExit(error = Get().Open()); + SuccessOrExit(error = Get().Bind(SendRelayTransmit, this)); + Get().SetConnectCallback(HandleSecureAgentConnectEvent, this); mStateCallback.Set(aStateCallback, aCallbackContext); @@ -287,7 +289,7 @@ Error Commissioner::Start(StateCallback aStateCallback, JoinerCallback aJoinerCa exit: if ((error != kErrorNone) && (error != kErrorAlready)) { - Get().Stop(); + Get().Close(); LogWarnOnError(error, "start commissioner"); } @@ -302,7 +304,7 @@ Error Commissioner::Stop(ResignMode aResignMode) VerifyOrExit(mState != kStateDisabled, error = kErrorAlready); mJoinerSessionTimer.Stop(); - Get().Stop(); + Get().Close(); if (mState == kStateActive) { @@ -942,7 +944,7 @@ template <> void Commissioner::HandleTmf(Coap::Message &aMessage, c joinerMessageInfo.GetPeerAddr().SetIid(mJoinerIid); joinerMessageInfo.SetPeerPort(mJoinerPort); - Get().HandleUdpReceive(aMessage, joinerMessageInfo); + Get().HandleReceive(aMessage, joinerMessageInfo); exit: return; @@ -1014,9 +1016,8 @@ exit: void Commissioner::SendJoinFinalizeResponse(const Coap::Message &aRequest, StateTlv::State aState) { - Error error = kErrorNone; - Ip6::MessageInfo joinerMessageInfo; - Coap::Message *message; + Error error = kErrorNone; + Coap::Message *message; message = Get().NewPriorityResponseMessage(aRequest); VerifyOrExit(message != nullptr, error = kErrorNoBufs); @@ -1026,15 +1027,11 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Message &aRequest, State SuccessOrExit(error = Tlv::Append(*message, aState)); - joinerMessageInfo.SetPeerAddr(Get().GetMeshLocalEid()); - joinerMessageInfo.GetPeerAddr().SetIid(mJoinerIid); - joinerMessageInfo.SetPeerPort(mJoinerPort); - #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE LogCertMessage("[THCI] direction=send | type=JOIN_FIN.rsp |", *message); #endif - SuccessOrExit(error = Get().SendMessage(*message, joinerMessageInfo)); + SuccessOrExit(error = Get().SendMessage(*message)); SignalJoinerEvent(kJoinerEventFinalize, mActiveJoiner); diff --git a/src/core/meshcop/commissioner.hpp b/src/core/meshcop/commissioner.hpp index a70f1ac22..f01dc11ce 100644 --- a/src/core/meshcop/commissioner.hpp +++ b/src/core/meshcop/commissioner.hpp @@ -418,8 +418,8 @@ private: Error aResult); void HandleLeaderKeepAliveResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult); - static void HandleSecureAgentConnectEvent(Dtls::ConnectEvent aEvent, void *aContext); - void HandleSecureAgentConnectEvent(Dtls::ConnectEvent aEvent); + static void HandleSecureAgentConnectEvent(Dtls::Session::ConnectEvent aEvent, void *aContext); + void HandleSecureAgentConnectEvent(Dtls::Session::ConnectEvent aEvent); template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index 4269c071b..fea808e49 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -137,7 +137,8 @@ Error Joiner::Start(const char *aPskd, Get().SetExtAddress(randomAddress); Get().UpdateLinkLocalAddress(); - SuccessOrExit(error = Get().Start(kJoinerUdpPort)); + SuccessOrExit(error = Get().Open()); + SuccessOrExit(error = Get().Bind(kJoinerUdpPort)); Get().SetConnectCallback(HandleSecureCoapClientConnect, this); Get().SetPsk(joinerPskd); @@ -202,7 +203,7 @@ void Joiner::Finish(Error aError) OT_FALL_THROUGH; case kStateDiscover: - Get().Stop(); + Get().Close(); break; } @@ -368,16 +369,16 @@ exit: return error; } -void Joiner::HandleSecureCoapClientConnect(Dtls::ConnectEvent aEvent, void *aContext) +void Joiner::HandleSecureCoapClientConnect(Dtls::Session::ConnectEvent aEvent, void *aContext) { static_cast(aContext)->HandleSecureCoapClientConnect(aEvent); } -void Joiner::HandleSecureCoapClientConnect(Dtls::ConnectEvent aEvent) +void Joiner::HandleSecureCoapClientConnect(Dtls::Session::ConnectEvent aEvent) { VerifyOrExit(mState == kStateConnect); - if (aEvent == Dtls::kConnected) + if (aEvent == Dtls::Session::kConnected) { SetState(kStateConnected); SendJoinerFinalize(); diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp index 5c5f03383..e310db79f 100644 --- a/src/core/meshcop/joiner.hpp +++ b/src/core/meshcop/joiner.hpp @@ -193,8 +193,8 @@ private: static void HandleDiscoverResult(Mle::DiscoverScanner::ScanResult *aResult, void *aContext); void HandleDiscoverResult(Mle::DiscoverScanner::ScanResult *aResult); - static void HandleSecureCoapClientConnect(Dtls::ConnectEvent aEvent, void *aContext); - void HandleSecureCoapClientConnect(Dtls::ConnectEvent aEvent); + static void HandleSecureCoapClientConnect(Dtls::Session::ConnectEvent aEvent, void *aContext); + void HandleSecureCoapClientConnect(Dtls::Session::ConnectEvent aEvent); static void HandleJoinerFinalizeResponse(void *aContext, otMessage *aMessage, diff --git a/src/core/meshcop/meshcop.hpp b/src/core/meshcop/meshcop.hpp index b3a36f36d..5ca504f14 100644 --- a/src/core/meshcop/meshcop.hpp +++ b/src/core/meshcop/meshcop.hpp @@ -105,6 +105,13 @@ public: */ uint8_t GetLength(void) const { return static_cast(StringLength(m8, kMaxLength + 1)); } + /** + * Gets the PSKd as a byte array. + * + * @returns The PSKd as a byte array. + */ + const uint8_t *GetBytes(void) const { return reinterpret_cast(m8); } + /** * Overloads operator `==` to evaluate whether or not two PSKds are equal. * diff --git a/src/core/meshcop/secure_transport.cpp b/src/core/meshcop/secure_transport.cpp index 018e45733..6ce570553 100644 --- a/src/core/meshcop/secure_transport.cpp +++ b/src/core/meshcop/secure_transport.cpp @@ -76,8 +76,7 @@ const int SecureTransport::kCipherSuites[][2] = { // SecureTransport SecureTransport::SecureTransport(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity, bool aDatagramTransport) - : InstanceLocator(aInstance) - , mLayerTwoSecurity(aLayerTwoSecurity) + : mLayerTwoSecurity(aLayerTwoSecurity) , mDatagramTransport(aDatagramTransport) , mIsOpen(false) , mIsServer(true) @@ -505,6 +504,13 @@ exit: return error; } +void SecureTransport::SetPsk(const JoinerPskd &aPskd) +{ + static_assert(JoinerPskd::kMaxLength <= kPskMaxLength, "The max DTLS PSK length is smaller than joiner PSKd"); + + IgnoreError(SetPsk(aPskd.GetBytes(), aPskd.GetLength())); +} + Error SecureSession::Send(Message &aMessage) { Error error = kErrorNone; @@ -715,7 +721,7 @@ void SecureTransport::HandleMbedtlsExportKeys(mbedtls_ssl_key_export_type aType, sha256.Update(keyBlock, kSecureTransportKeyBlockSize); sha256.Finish(kek); - Get().SetKek(kek.GetBytes()); + mTimer.Get().SetKek(kek.GetBytes()); exit: return; @@ -751,7 +757,7 @@ int SecureTransport::HandleMbedtlsExportKeys(const unsigned char *aMasterSecret, sha256.Update(aKeyBlock, 2 * static_cast(aMacLength + aKeyLength + aIvLength)); sha256.Finish(kek); - Get().SetKek(kek.GetBytes()); + mTimer.Get().SetKek(kek.GetBytes()); exit: return 0; diff --git a/src/core/meshcop/secure_transport.hpp b/src/core/meshcop/secure_transport.hpp index 7517cc9ec..81f4a3ca7 100644 --- a/src/core/meshcop/secure_transport.hpp +++ b/src/core/meshcop/secure_transport.hpp @@ -81,6 +81,7 @@ #include "common/random.hpp" #include "common/timer.hpp" #include "crypto/sha256.hpp" +#include "meshcop/meshcop.hpp" #include "meshcop/meshcop_tlvs.hpp" #include "net/socket.hpp" #include "net/udp6.hpp" @@ -202,6 +203,16 @@ public: */ bool IsConnected(void) const { return (mState == kStateConnected); } + /** + * Gets the `SecureTransport` used by this session. + * + * @return The `SecureTransport` instance associated with this session. + */ + SecureTransport &GetTransport(void) { return mTransport; } + +protected: + explicit SecureSession(SecureTransport &aTransport); + private: static constexpr uint32_t kGuardTimeNewConnectionMilli = 2000; static constexpr uint16_t kMaxContentLen = OPENTHREAD_CONFIG_DTLS_MAX_CONTENT_LEN; @@ -221,8 +232,6 @@ private: 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; } @@ -273,7 +282,7 @@ private: /** * Represents a secure transport, used as base class for `Dtls` and `Tls`. */ -class SecureTransport : public InstanceLocator +class SecureTransport : private NonCopyable { friend class SecureSession; @@ -604,6 +613,13 @@ public: */ Error SetPsk(const uint8_t *aPsk, uint8_t aPskLength); + /** + * Sets the PSK. + * + * @param[in] aPskd A Joiner PSKd. + */ + void SetPsk(const JoinerPskd &aPskd); + /** * 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. @@ -726,48 +742,61 @@ private: }; /** - * Represents a DTLS instance. + * Defines DTLS `Transport` and `Session`. */ -class Dtls : public SecureTransport, public SecureSession +class Dtls { public: + class Session; + /** - * Initializes the `Dtls` object. - * - * @param[in] aInstance A reference to the OpenThread instance. - * @param[in] aLayerTwoSecurity Specifies whether to use layer two security or not. + * Represents a DTLS transport. */ - Dtls(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity) - : SecureTransport(aInstance, aLayerTwoSecurity, /* aDatagramTransport */ true) - , SecureSession(*static_cast(this)) + class Transport : public SecureTransport { - SetSession(*static_cast(this)); - } -}; + friend class Session; -#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE + public: + /** + * Initializes the `Dtls::Transport` object. + * + * @param[in] aInstance A reference to the OpenThread instance. + * @param[in] aLayerTwoSecurity Specifies whether to use layer two security or not. + */ + Transport(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity) + : SecureTransport(aInstance, aLayerTwoSecurity, /* aDatagramTransport */ true) + { + } + + private: + void SetSession(Session &aSesssion) { SecureTransport::SetSession(aSesssion); } + }; -/** - * Represents an extended DTLS instance providing `Dtls::Extension` APIs. - */ -class DtlsExtended : public Dtls -{ -public: /** - * Initializes the `DtlsExtended` object. - * - * @param[in] aInstance A reference to the OpenThread instance. - * @param[in] aLayerTwoSecurity Specifies whether to use layer two security or not. - * @param[in] aExtension An extension providing additional configuration methods. + * Represents a DTLS session. */ - DtlsExtended(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity, Extension &aExtension) - : Dtls(aInstance, aLayerTwoSecurity) + class Session : public SecureSession { - SetExtension(aExtension); - } -}; + public: + /** + * Initializes the `Dtls::Session` object. + * + * @param[in] aTransport The DTLS transport to use for this session. + */ + Session(Transport &aTransport) + : SecureSession(aTransport) + { + aTransport.SetSession(*this); + } -#endif + /** + * Returns the DTLS transport used by this session. + * + * @returns The DTLS transport associated with this session. + */ + Transport &GetTransport(void) { return static_cast(SecureSession::GetTransport()); } + }; +}; #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE diff --git a/src/core/thread/thread_netif.cpp b/src/core/thread/thread_netif.cpp index b46134ab3..9c30caad9 100644 --- a/src/core/thread/thread_netif.cpp +++ b/src/core/thread/thread_netif.cpp @@ -88,7 +88,7 @@ void ThreadNetif::Down(void) Get().Stop(); #endif #if OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE - Get().Stop(); + Get().Close(); #endif IgnoreError(Get().Stop()); IgnoreError(Get().Disable()); diff --git a/src/core/thread/tmf.cpp b/src/core/thread/tmf.cpp index d2d6ce3cd..89671db9e 100644 --- a/src/core/thread/tmf.cpp +++ b/src/core/thread/tmf.cpp @@ -273,8 +273,8 @@ Message::Priority Agent::DscpToPriority(uint8_t aDscp) #if OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE SecureAgent::SecureAgent(Instance &aInstance) - : Coap::CoapSecureBase(aInstance, mDtls) - , mDtls(aInstance, kNoLinkSecurity) + : Coap::Dtls::Transport(aInstance, kNoLinkSecurity) + , Coap::SecureSession(aInstance, static_cast(*this)) { SetResourceHandler(&HandleResource); } diff --git a/src/core/thread/tmf.hpp b/src/core/thread/tmf.hpp index 9177ce766..869e45c20 100644 --- a/src/core/thread/tmf.hpp +++ b/src/core/thread/tmf.hpp @@ -197,7 +197,7 @@ private: /** * Implements functionality of the secure TMF agent. */ -class SecureAgent : public Coap::CoapSecureBase +class SecureAgent : public Coap::Dtls::Transport, public Coap::SecureSession { public: /** @@ -213,8 +213,6 @@ private: Message &aMessage, const Ip6::MessageInfo &aMessageInfo); bool HandleResource(const char *aUriPath, Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - - MeshCoP::Dtls mDtls; }; #endif diff --git a/tests/nexus/test_dtls.cpp b/tests/nexus/test_dtls.cpp index 1b008aa93..9a93106cf 100644 --- a/tests/nexus/test_dtls.cpp +++ b/tests/nexus/test_dtls.cpp @@ -45,29 +45,29 @@ static constexpr uint16_t kMaxAttempts = 3; static const uint8_t kPsk[] = {0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x16}; -static Dtls::ConnectEvent sDtlsEvent[kMaxNodes]; +static Dtls::Session::ConnectEvent sDtlsEvent[kMaxNodes]; static Array sDtlsLastReceive[kMaxNodes]; static bool sDtlsAutoClosed[kMaxNodes]; -const char *ConnectEventToString(Dtls::ConnectEvent aEvent) +const char *ConnectEventToString(Dtls::Session::ConnectEvent aEvent) { const char *str = ""; switch (aEvent) { - case Dtls::kConnected: + case Dtls::Session::kConnected: str = "kConnected"; break; - case Dtls::kDisconnectedPeerClosed: + case Dtls::Session::kDisconnectedPeerClosed: str = "kDisconnectedPeerClosed"; break; - case Dtls::kDisconnectedLocalClosed: + case Dtls::Session::kDisconnectedLocalClosed: str = "kDisconnectedLocalClosed"; break; - case Dtls::kDisconnectedMaxAttempts: + case Dtls::Session::kDisconnectedMaxAttempts: str = "kDisconnectedMaxAttempts"; break; - case Dtls::kDisconnectedError: + case Dtls::Session::kDisconnectedError: str = "kDisconnectedError"; break; } @@ -92,7 +92,7 @@ void HandleReceive(void *aContext, uint8_t *aBuf, uint16_t aLength) } } -void HandleConnectEvent(Dtls::ConnectEvent aEvent, void *aContext) +void HandleConnectEvent(Dtls::Session::ConnectEvent aEvent, void *aContext) { Node *node = static_cast(aContext); @@ -131,6 +131,17 @@ OwnedPtr PrepareMessage(Node &aNode) return OwnedPtr(message); } +class DtlsTransportAndSession : public InstanceLocator, public Dtls::Transport, public Dtls::Session +{ +public: + explicit DtlsTransportAndSession(Node &aNode) + : InstanceLocator(aNode.GetInstance()) + , Dtls::Transport(aNode.GetInstance(), kWithLinkSecurity) + , Dtls::Session(static_cast(*this)) + { + } +}; + void TestDtls(void) { Core nexus; @@ -159,10 +170,10 @@ void TestDtls(void) Log("------------------------------------------------------------------------------------------------------"); { - Dtls dtls0(node0.GetInstance(), kWithLinkSecurity); - Dtls dtls1(node1.GetInstance(), kWithLinkSecurity); - Dtls dtls2(node2.GetInstance(), kWithLinkSecurity); - Ip6::SockAddr sockAddr; + DtlsTransportAndSession dtls0(node0); + DtlsTransportAndSession dtls1(node1); + DtlsTransportAndSession dtls2(node2); + Ip6::SockAddr sockAddr; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log("Start DTLS (server) on node0 bound to port %u", kUdpPort); @@ -191,7 +202,7 @@ void TestDtls(void) for (uint16_t iter = 0; iter <= kMaxAttempts + 1; iter++) { - memset(sDtlsEvent, Dtls::kConnected, sizeof(sDtlsEvent)); + memset(sDtlsEvent, Dtls::Session::kConnected, sizeof(sDtlsEvent)); SuccessOrQuit(dtls1.Connect(sockAddr)); nexus.AdvanceTime(3 * Time::kOneSecondInMsec); @@ -199,8 +210,8 @@ void TestDtls(void) VerifyOrQuit(!dtls0.IsConnected()); VerifyOrQuit(!dtls1.IsConnected()); - VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::kDisconnectedError); - VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::kDisconnectedError); + VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::Session::kDisconnectedError); + VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::Session::kDisconnectedError); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -219,8 +230,8 @@ void TestDtls(void) VerifyOrQuit(dtls0.IsConnected()); VerifyOrQuit(dtls1.IsConnected()); - VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::kConnected); - VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::kConnected); + VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::Session::kConnected); + VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::Session::kConnected); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log("Send message (random data and length) over DTLS session from node0 to node1"); @@ -260,8 +271,8 @@ void TestDtls(void) VerifyOrQuit(!dtls0.IsConnected()); VerifyOrQuit(!dtls1.IsConnected()); - VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::kDisconnectedPeerClosed); - VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::kDisconnectedLocalClosed); + VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::Session::kDisconnectedPeerClosed); + VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::Session::kDisconnectedLocalClosed); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log("Establish a DTLS connection again"); @@ -273,8 +284,8 @@ void TestDtls(void) VerifyOrQuit(dtls0.IsConnected()); VerifyOrQuit(dtls1.IsConnected()); - VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::kConnected); - VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::kConnected); + VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::Session::kConnected); + VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::Session::kConnected); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log("Try to connect from node2 - validate that it fails to connect since already connected"); @@ -302,8 +313,8 @@ void TestDtls(void) VerifyOrQuit(!dtls1.IsConnected()); VerifyOrQuit(!dtls2.IsConnected()); - VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::kDisconnectedLocalClosed); - VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::kDisconnectedPeerClosed); + VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::Session::kDisconnectedLocalClosed); + VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::Session::kDisconnectedPeerClosed); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -339,7 +350,7 @@ void TestDtls(void) for (uint16_t iter = 0; iter < kMaxAttempts - 1; iter++) { - memset(sDtlsEvent, Dtls::kConnected, sizeof(sDtlsEvent)); + memset(sDtlsEvent, Dtls::Session::kConnected, sizeof(sDtlsEvent)); SuccessOrQuit(dtls1.Connect(sockAddr)); nexus.AdvanceTime(3 * Time::kOneSecondInMsec); @@ -347,20 +358,20 @@ void TestDtls(void) VerifyOrQuit(!dtls0.IsConnected()); VerifyOrQuit(!dtls1.IsConnected()); - VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::kDisconnectedError); - VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::kDisconnectedError); + VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::Session::kDisconnectedError); + VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::Session::kDisconnectedError); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Log("Using wrong PSK try one last time, validate the auto-close behavior"); - memset(sDtlsEvent, Dtls::kConnected, sizeof(sDtlsEvent)); + memset(sDtlsEvent, Dtls::Session::kConnected, sizeof(sDtlsEvent)); SuccessOrQuit(dtls1.Connect(sockAddr)); nexus.AdvanceTime(3 * Time::kOneSecondInMsec); - VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::kDisconnectedMaxAttempts); - VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::kDisconnectedError); + VerifyOrQuit(sDtlsEvent[node0.GetId()] == Dtls::Session::kDisconnectedMaxAttempts); + VerifyOrQuit(sDtlsEvent[node1.GetId()] == Dtls::Session::kDisconnectedError); VerifyOrQuit(sDtlsAutoClosed[node0.GetId()]);