[dtls] refine CoAP secure and DTLS (#3632)

`CoapSecure` is always used by joiner, border agent or commissioner.
DTLS should not be shared with the application `CoapSecure`.

This commit includes the following changes:
* allow multiple DTLS by using `TimerMilliContext`
* move `CoAP::mSocket` into `Dtls`
* move `ThreadNetif::mDtls` into `CoapSecure`
* remove unnecessary getters of `Dtls` and `CoapSecure`
This commit is contained in:
Yakun Xu
2019-03-08 08:11:41 -08:00
committed by Jonathan Hui
parent 96725a985e
commit 7a0eb2c2e7
14 changed files with 386 additions and 319 deletions
+2 -4
View File
@@ -78,21 +78,19 @@ typedef void (*otHandleCoapSecureClientConnect)(bool aConnected, void *aContext)
* *
* @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPort The local UDP port to bind to. * @param[in] aPort The local UDP port to bind to.
* @param[in] aContext A pointer to arbitrary context information.
* *
* @retval OT_ERROR_NONE Successfully started the CoAP Secure server. * @retval OT_ERROR_NONE Successfully started the CoAP Secure server.
* *
*/ */
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort, void *aContext); otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort);
/** /**
* This function stops the CoAP Secure server. * This function stops the CoAP Secure server.
* *
* @param[in] aInstance A pointer to an OpenThread instance. * @param[in] aInstance A pointer to an OpenThread instance.
* *
* @retval OT_ERROR_NONE Successfully stopped the CoAP Secure server.
*/ */
otError otCoapSecureStop(otInstance *aInstance); void otCoapSecureStop(otInstance *aInstance);
/** /**
* This method sets the Pre-Shared Key (PSK) and cipher suite * This method sets the Pre-Shared Key (PSK) and cipher suite
+7 -15
View File
@@ -147,7 +147,7 @@ otError CoapSecure::Process(int argc, char *argv[])
} }
} }
otCoapSecureSetSslAuthMode(mInterpreter.mInstance, mVerifyPeerCert); otCoapSecureSetSslAuthMode(mInterpreter.mInstance, mVerifyPeerCert);
SuccessOrExit(error = otCoapSecureStart(mInterpreter.mInstance, OT_DEFAULT_COAP_SECURE_PORT, this)); SuccessOrExit(error = otCoapSecureStart(mInterpreter.mInstance, OT_DEFAULT_COAP_SECURE_PORT));
otCoapSecureSetClientConnectedCallback(mInterpreter.mInstance, &CoapSecure::HandleClientConnect, this); otCoapSecureSetClientConnectedCallback(mInterpreter.mInstance, &CoapSecure::HandleClientConnect, this);
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER #if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
otCoapSecureSetDefaultHandler(mInterpreter.mInstance, &CoapSecure::DefaultHandle, this); otCoapSecureSetDefaultHandler(mInterpreter.mInstance, &CoapSecure::DefaultHandle, this);
@@ -274,7 +274,7 @@ otError CoapSecure::Process(int argc, char *argv[])
} }
else else
{ {
SuccessOrExit(error = Stop()); Stop();
} }
} }
else if (strcmp(argv[0], "help") == 0) else if (strcmp(argv[0], "help") == 0)
@@ -311,13 +311,11 @@ exit:
return error; return error;
} }
otError CoapSecure::Stop(void) void CoapSecure::Stop(void)
{ {
otError error = OT_ERROR_ABORT;
otCoapRemoveResource(mInterpreter.mInstance, &mResource); otCoapRemoveResource(mInterpreter.mInstance, &mResource);
error = otCoapSecureStop(mInterpreter.mInstance); otCoapSecureStop(mInterpreter.mInstance);
mInterpreter.mServer->OutputFormat("Coap Secure service stopped: "); mInterpreter.mServer->OutputFormat("Coap Secure service stopped");
return error;
} }
void OTCALL CoapSecure::HandleClientConnect(bool aConnected, void *aContext) void OTCALL CoapSecure::HandleClientConnect(bool aConnected, void *aContext)
@@ -342,14 +340,8 @@ void CoapSecure::HandleClientConnect(bool aConnected)
else else
{ {
mInterpreter.mServer->OutputFormat("CoAP Secure disconnected before stop.\r\n> "); mInterpreter.mServer->OutputFormat("CoAP Secure disconnected before stop.\r\n> ");
if (Stop() == OT_ERROR_NONE) Stop();
{ mInterpreter.mServer->OutputFormat(" Done\r\n> ");
mInterpreter.mServer->OutputFormat(" Done\r\n> ");
}
else
{
mInterpreter.mServer->OutputFormat(" With error\r\n> ");
}
mShutdownFlag = false; mShutdownFlag = false;
} }
} }
+1 -1
View File
@@ -90,7 +90,7 @@ private:
otError ProcessRequest(int argc, char *argv[]); otError ProcessRequest(int argc, char *argv[]);
otError Stop(void); void Stop(void);
static void OTCALL HandleServerResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); static void OTCALL HandleServerResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleServerResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo); void HandleServerResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo);
+4 -4
View File
@@ -44,11 +44,11 @@
using namespace ot; using namespace ot;
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort, void *aContext) otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort)
{ {
Instance &instance = *static_cast<Instance *>(aInstance); Instance &instance = *static_cast<Instance *>(aInstance);
return instance.GetApplicationCoapSecure().Start(aPort, NULL, aContext); return instance.GetApplicationCoapSecure().Start(aPort);
} }
otError otCoapSecureSetCertificate(otInstance * aInstance, otError otCoapSecureSetCertificate(otInstance * aInstance,
@@ -184,11 +184,11 @@ bool otCoapSecureIsConnectionActive(otInstance *aInstance)
return instance.GetApplicationCoapSecure().IsConnectionActive(); return instance.GetApplicationCoapSecure().IsConnectionActive();
} }
otError otCoapSecureStop(otInstance *aInstance) void otCoapSecureStop(otInstance *aInstance)
{ {
Instance &instance = *static_cast<Instance *>(aInstance); Instance &instance = *static_cast<Instance *>(aInstance);
return instance.GetApplicationCoapSecure().Stop(); instance.GetApplicationCoapSecure().Stop();
} }
otError otCoapSecureSendRequest(otInstance * aInstance, otError otCoapSecureSendRequest(otInstance * aInstance,
+32 -182
View File
@@ -49,35 +49,37 @@ namespace Coap {
CoapSecure::CoapSecure(Instance &aInstance, bool aLayerTwoSecurity) CoapSecure::CoapSecure(Instance &aInstance, bool aLayerTwoSecurity)
: CoapBase(aInstance, &CoapSecure::Send) : CoapBase(aInstance, &CoapSecure::Send)
, mDtls(aInstance, aLayerTwoSecurity)
, mConnectedCallback(NULL) , mConnectedCallback(NULL)
, mConnectedContext(NULL) , mConnectedContext(NULL)
, mTransportCallback(NULL)
, mTransportContext(NULL)
, mTransmitQueue() , mTransmitQueue()
, mTransmitTask(aInstance, &CoapSecure::HandleTransmit, this) , mTransmitTask(aInstance, &CoapSecure::HandleTransmit, this)
, mSocket(aInstance.GetThreadNetif().GetIp6().GetUdp())
, mLayerTwoSecurity(aLayerTwoSecurity)
{ {
} }
otError CoapSecure::Start(uint16_t aPort, TransportCallback aCallback, void *aContext) otError CoapSecure::Start(uint16_t aPort)
{ {
otError error = OT_ERROR_NONE; otError error = OT_ERROR_NONE;
mTransportCallback = aCallback;
mTransportContext = aContext;
mConnectedCallback = NULL; mConnectedCallback = NULL;
mConnectedContext = NULL; mConnectedContext = NULL;
// Passing mTransportCallback means that we do not want to use socket SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
// to transmit/receive messages, so do not open it in that case. SuccessOrExit(error = mDtls.Bind(aPort));
if (mTransportCallback == NULL)
{
Ip6::SockAddr sockaddr;
sockaddr.mPort = aPort; exit:
SuccessOrExit(error = mSocket.Open(&CoapSecure::HandleUdpReceive, this)); return error;
VerifyOrExit((error = mSocket.Bind(sockaddr)) == OT_ERROR_NONE, mSocket.Close()); }
}
otError CoapSecure::Start(MeshCoP::Dtls::TransportCallback aCallback, void *aContext)
{
otError error = OT_ERROR_NONE;
mConnectedCallback = NULL;
mConnectedContext = NULL;
SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
SuccessOrExit(error = mDtls.Bind(aCallback, aContext));
exit: exit:
return error; return error;
@@ -89,16 +91,9 @@ void CoapSecure::SetConnectedCallback(ConnectedCallback aCallback, void *aContex
mConnectedContext = aContext; mConnectedContext = aContext;
} }
otError CoapSecure::Stop(void) void CoapSecure::Stop(void)
{ {
otError error; mDtls.Stop();
SuccessOrExit(error = mSocket.Close());
if (IsConnectionActive())
{
Disconnect();
}
for (ot::Message *message = mTransmitQueue.GetHead(); message != NULL; message = message->GetNext()) for (ot::Message *message = mTransmitQueue.GetHead(); message != NULL; message = message->GetNext())
{ {
@@ -106,66 +101,20 @@ otError CoapSecure::Stop(void)
message->Free(); message->Free();
} }
mTransportCallback = NULL;
mTransportContext = NULL;
ClearRequestsAndResponses(); ClearRequestsAndResponses();
exit:
return error;
} }
otError CoapSecure::Connect(const Ip6::SockAddr &aSockAddr, ConnectedCallback aCallback, void *aContext) otError CoapSecure::Connect(const Ip6::SockAddr &aSockAddr, ConnectedCallback aCallback, void *aContext)
{ {
memcpy(&mPeerAddress.mPeerAddr, &aSockAddr.mAddress, sizeof(mPeerAddress.mPeerAddr));
mPeerAddress.mPeerPort = aSockAddr.mPort;
if (aSockAddr.GetAddress().IsLinkLocal() || aSockAddr.GetAddress().IsMulticast())
{
mPeerAddress.mInterfaceId = aSockAddr.mScopeId;
}
else
{
mPeerAddress.mInterfaceId = 0;
}
mConnectedCallback = aCallback; mConnectedCallback = aCallback;
mConnectedContext = aContext; mConnectedContext = aContext;
return GetNetif().GetDtls().Start(true, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive, return mDtls.Connect(aSockAddr);
&CoapSecure::HandleDtlsSend, this);
}
bool CoapSecure::IsConnectionActive(void)
{
return GetNetif().GetDtls().GetState() != MeshCoP::Dtls::kStateStopped;
}
bool CoapSecure::IsConnected(void)
{
return GetNetif().GetDtls().GetState() == MeshCoP::Dtls::kStateConnected;
}
void CoapSecure::Disconnect(void)
{
GetNetif().GetDtls().Stop();
// Disconnect from previous peer by connecting to any address
{
otError error = mSocket.Connect(Ip6::SockAddr());
assert(error == OT_ERROR_NONE);
}
}
MeshCoP::Dtls &CoapSecure::GetDtls(void)
{
return GetNetif().GetDtls();
} }
otError CoapSecure::SetPsk(const uint8_t *aPsk, uint8_t aPskLength) otError CoapSecure::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
{ {
return GetNetif().GetDtls().SetPsk(aPsk, aPskLength); return mDtls.SetPsk(aPsk, aPskLength);
} }
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE #if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
@@ -176,12 +125,12 @@ otError CoapSecure::SetCertificate(const uint8_t *aX509Cert,
const uint8_t *aPrivateKey, const uint8_t *aPrivateKey,
uint32_t aPrivateKeyLength) uint32_t aPrivateKeyLength)
{ {
return GetNetif().GetDtls().SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength); return mDtls.SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
} }
otError CoapSecure::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength) otError CoapSecure::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength)
{ {
return GetNetif().GetDtls().SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength); return mDtls.SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
} }
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
@@ -191,14 +140,14 @@ otError CoapSecure::SetPreSharedKey(const uint8_t *aPsk,
const uint8_t *aPskIdentity, const uint8_t *aPskIdentity,
uint16_t aPskIdLength) uint16_t aPskIdLength)
{ {
return GetNetif().GetDtls().SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength); return mDtls.SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength);
} }
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED #endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
#ifdef MBEDTLS_BASE64_C #ifdef MBEDTLS_BASE64_C
otError CoapSecure::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize) otError CoapSecure::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize)
{ {
return GetNetif().GetDtls().GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize); return mDtls.GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize);
} }
#endif // MBEDTLS_BASE64_C #endif // MBEDTLS_BASE64_C
@@ -210,7 +159,7 @@ void CoapSecure::SetClientConnectedCallback(ConnectedCallback aCallback, void *a
void CoapSecure::SetSslAuthMode(bool aVerifyPeerCertificate) void CoapSecure::SetSslAuthMode(bool aVerifyPeerCertificate)
{ {
GetNetif().GetDtls().SetSslAuthMode(aVerifyPeerCertificate); mDtls.SetSslAuthMode(aVerifyPeerCertificate);
} }
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
@@ -221,7 +170,7 @@ otError CoapSecure::SendMessage(Message &aMessage, otCoapResponseHandler aHandle
VerifyOrExit(IsConnected(), error = OT_ERROR_INVALID_STATE); VerifyOrExit(IsConnected(), error = OT_ERROR_INVALID_STATE);
error = CoapBase::SendMessage(aMessage, mPeerAddress, aHandler, aContext); error = CoapBase::SendMessage(aMessage, mDtls.GetPeerAddress(), aHandler, aContext);
exit: exit:
return error; return error;
@@ -238,6 +187,7 @@ otError CoapSecure::SendMessage(Message & aMessage,
otError CoapSecure::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) otError CoapSecure::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{ {
OT_UNUSED_VARIABLE(aMessageInfo); OT_UNUSED_VARIABLE(aMessageInfo);
otError error; otError error;
SuccessOrExit(error = mTransmitQueue.Enqueue(aMessage)); SuccessOrExit(error = mTransmitQueue.Enqueue(aMessage));
@@ -247,57 +197,6 @@ exit:
return error; return error;
} }
void CoapSecure::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
static_cast<CoapSecure *>(aContext)->HandleUdpReceive(*static_cast<ot::Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
}
void CoapSecure::HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
ThreadNetif &netif = GetNetif();
if (netif.GetDtls().GetState() == MeshCoP::Dtls::kStateStopped)
{
Ip6::SockAddr sockAddr;
sockAddr.mAddress = aMessageInfo.GetPeerAddr();
sockAddr.mPort = aMessageInfo.GetPeerPort();
mSocket.Connect(sockAddr);
mPeerAddress.SetPeerAddr(aMessageInfo.GetPeerAddr());
mPeerAddress.SetPeerPort(aMessageInfo.GetPeerPort());
mPeerAddress.SetInterfaceId(aMessageInfo.GetInterfaceId());
if (netif.IsUnicastAddress(aMessageInfo.GetSockAddr()))
{
mPeerAddress.SetSockAddr(aMessageInfo.GetSockAddr());
}
mPeerAddress.SetSockPort(aMessageInfo.GetSockPort());
VerifyOrExit(netif.GetDtls().Start(false, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive,
CoapSecure::HandleDtlsSend, this) == OT_ERROR_NONE);
}
else
{
// Once DTLS session is started, communicate only with a peer.
VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
(mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()));
}
#if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER
if (netif.GetDtls().GetState() == MeshCoP::Dtls::kStateConnecting)
{
netif.GetDtls().SetClientId(mPeerAddress.GetPeerAddr().mFields.m8, sizeof(mPeerAddress.GetPeerAddr().mFields));
}
#endif
netif.GetDtls().Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());
exit:
return;
}
void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected) void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)
{ {
return static_cast<CoapSecure *>(aContext)->HandleDtlsConnected(aConnected); return static_cast<CoapSecure *>(aContext)->HandleDtlsConnected(aConnected);
@@ -305,14 +204,6 @@ void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)
void CoapSecure::HandleDtlsConnected(bool aConnected) void CoapSecure::HandleDtlsConnected(bool aConnected)
{ {
if (!aConnected)
{
// Disconnect from previous peer by connecting to any address
otError error = mSocket.Connect(Ip6::SockAddr());
assert(error == OT_ERROR_NONE);
}
if (mConnectedCallback != NULL) if (mConnectedCallback != NULL)
{ {
mConnectedCallback(aConnected, mConnectedContext); mConnectedCallback(aConnected, mConnectedContext);
@@ -332,7 +223,7 @@ void CoapSecure::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
NULL); NULL);
SuccessOrExit(message->Append(aBuf, aLength)); SuccessOrExit(message->Append(aBuf, aLength));
CoapBase::Receive(*message, mPeerAddress); CoapBase::Receive(*message, mDtls.GetPeerAddress());
exit: exit:
@@ -342,47 +233,6 @@ exit:
} }
} }
otError CoapSecure::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
{
return static_cast<CoapSecure *>(aContext)->HandleDtlsSend(aBuf, aLength, aMessageSubType);
}
otError CoapSecure::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
{
otError error = OT_ERROR_NONE;
ot::Message *message = NULL;
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
message->SetSubType(aMessageSubType);
message->SetLinkSecurityEnabled(mLayerTwoSecurity);
SuccessOrExit(error = message->Append(aBuf, aLength));
// Set message sub type in case Joiner Finalize Response is appended to the message.
if (aMessageSubType != Message::kSubTypeNone)
{
message->SetSubType(aMessageSubType);
}
if (mTransportCallback)
{
SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mPeerAddress));
}
else
{
SuccessOrExit(error = mSocket.SendTo(*message, mPeerAddress));
}
exit:
if (error != OT_ERROR_NONE && message != NULL)
{
message->Free();
}
return error;
}
void CoapSecure::HandleTransmit(Tasklet &aTasklet) void CoapSecure::HandleTransmit(Tasklet &aTasklet)
{ {
static_cast<CoapSecure *>(static_cast<TaskletContext &>(aTasklet).GetContext())->HandleTransmit(); static_cast<CoapSecure *>(static_cast<TaskletContext &>(aTasklet).GetContext())->HandleTransmit();
@@ -401,7 +251,7 @@ void CoapSecure::HandleTransmit(void)
mTransmitTask.Post(); mTransmitTask.Post();
} }
SuccessOrExit(error = GetDtls().Send(*message, message->GetLength())); SuccessOrExit(error = mDtls.Send(*message, message->GetLength()));
exit: exit:
if (error != OT_ERROR_NONE) if (error != OT_ERROR_NONE)
+22 -32
View File
@@ -57,16 +57,6 @@ public:
*/ */
typedef void (*ConnectedCallback)(bool aConnected, void *aContext); typedef void (*ConnectedCallback)(bool aConnected, void *aContext);
/**
* This function pointer is called when secure CoAP server want to send encrypted message.
*
* @param[in] aContext A pointer to arbitrary context information.
* @param[in] aMessage A reference to the message to send.
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
*
*/
typedef otError (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
/** /**
* This constructor initializes the object. * This constructor initializes the object.
* *
@@ -80,15 +70,24 @@ public:
* This method starts the secure CoAP agent. * This method starts the secure CoAP agent.
* *
* @param[in] aPort The local UDP port to bind to. * @param[in] aPort The local UDP port to bind to.
*
* @retval OT_ERROR_NONE Successfully started the CoAP agent.
* @retval OT_ERROR_ALREADY Already started.
*
*/
otError Start(uint16_t aPort);
/**
* This method 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] aCallback A pointer to a function for sending messages.
* If NULL, the message is sent directly to the socket.
* @param[in] aContext A pointer to arbitrary context information. * @param[in] aContext A pointer to arbitrary context information.
* *
* @retval OT_ERROR_NONE Successfully started the CoAP agent. * @retval OT_ERROR_NONE Successfully started the CoAP agent.
* @retval OT_ERROR_ALREADY Already started. * @retval OT_ERROR_ALREADY Already started.
* *
*/ */
otError Start(uint16_t aPort, TransportCallback aCallback = NULL, void *aContext = NULL); otError Start(MeshCoP::Dtls::TransportCallback aCallback, void *aContext);
/** /**
* This method sets connected callback of this secure CoAP agent. * This method sets connected callback of this secure CoAP agent.
@@ -102,10 +101,8 @@ public:
/** /**
* This method stops the secure CoAP agent. * This method stops the secure CoAP agent.
* *
* @retval OT_ERROR_NONE Successfully stopped the secure CoAP agent.
*
*/ */
otError Stop(void); void Stop(void);
/** /**
* This method initializes DTLS session with a peer. * This method initializes DTLS session with a peer.
@@ -126,7 +123,7 @@ public:
* @retval FALSE If DTLS session is not active. * @retval FALSE If DTLS session is not active.
* *
*/ */
bool IsConnectionActive(void); bool IsConnectionActive(void) { return mDtls.IsConnectionActive(); }
/** /**
* This method indicates whether or not the DTLS session is connected. * This method indicates whether or not the DTLS session is connected.
@@ -135,13 +132,13 @@ public:
* @retval FALSE The DTLS session is not connected. * @retval FALSE The DTLS session is not connected.
* *
*/ */
bool IsConnected(void); bool IsConnected(void) { return mDtls.IsConnected(); }
/** /**
* This method stops the DTLS connection. * This method stops the DTLS connection.
* *
*/ */
void Disconnect(void); void Disconnect(void) { mDtls.Close(); }
/** /**
* This method returns a reference to the DTLS object. * This method returns a reference to the DTLS object.
@@ -149,7 +146,7 @@ public:
* @returns A reference to the DTLS object. * @returns A reference to the DTLS object.
* *
*/ */
MeshCoP::Dtls &GetDtls(void); MeshCoP::Dtls &GetDtls(void) { return mDtls; }
/** /**
* This method sets the PSK. * This method sets the PSK.
@@ -306,7 +303,10 @@ public:
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage. * @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
* *
*/ */
void HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); void HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
return mDtls.HandleUdpReceive(aMessage, aMessageInfo);
}
/** /**
* This method returns the DTLS session's peer address. * This method returns the DTLS session's peer address.
@@ -314,7 +314,7 @@ public:
* @return DTLS session's message info. * @return DTLS session's message info.
* *
*/ */
const Ip6::MessageInfo &GetPeerMessageInfo(void) const { return mPeerAddress; } const Ip6::MessageInfo &GetPeerAddress(void) const { return mDtls.GetPeerAddress(); }
private: private:
static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
@@ -329,24 +329,14 @@ private:
static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength); static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength);
void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength); void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength);
static otError HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
otError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
static void HandleTransmit(Tasklet &aTasklet); static void HandleTransmit(Tasklet &aTasklet);
void HandleTransmit(void); void HandleTransmit(void);
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); MeshCoP::Dtls mDtls;
Ip6::MessageInfo mPeerAddress;
ConnectedCallback mConnectedCallback; ConnectedCallback mConnectedCallback;
void * mConnectedContext; void * mConnectedContext;
TransportCallback mTransportCallback;
void * mTransportContext;
MessageQueue mTransmitQueue; MessageQueue mTransmitQueue;
TaskletContext mTransmitTask; TaskletContext mTransmitTask;
Ip6::UdpSocket mSocket;
bool mLayerTwoSecurity : 1;
}; };
} // namespace Coap } // namespace Coap
-12
View File
@@ -623,18 +623,6 @@ template <> inline Dns::Client &Instance::Get(void)
} }
#endif #endif
#if OPENTHREAD_ENABLE_DTLS
template <> inline MeshCoP::Dtls &Instance::Get(void)
{
return GetThreadNetif().GetDtls();
}
template <> inline Coap::CoapSecure &Instance::Get(void)
{
return GetThreadNetif().GetCoapSecure();
}
#endif
#if OPENTHREAD_ENABLE_DHCP6_CLIENT #if OPENTHREAD_ENABLE_DHCP6_CLIENT
template <> inline Dhcp6::Dhcp6Client &Instance::Get(void) template <> inline Dhcp6::Dhcp6Client &Instance::Get(void)
{ {
+6 -7
View File
@@ -164,7 +164,7 @@ static void SendErrorMessage(Coap::CoapSecure &aCoapSecure, ForwardContext &aFor
VerifyOrExit((message = NewMeshCoPMessage(aCoapSecure)) != NULL, error = OT_ERROR_NO_BUFS); VerifyOrExit((message = NewMeshCoPMessage(aCoapSecure)) != NULL, error = OT_ERROR_NO_BUFS);
aForwardContext.ToHeader(*message, CoapCodeFromError(error)); aForwardContext.ToHeader(*message, CoapCodeFromError(error));
SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerMessageInfo())); SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerAddress()));
exit: exit:
if (error != OT_ERROR_NONE) if (error != OT_ERROR_NONE)
@@ -197,7 +197,7 @@ static void SendErrorMessage(Coap::CoapSecure &aCoapSecure, const Coap::Message
message->SetMessageId(aSeparate ? 0 : aRequest.GetMessageId()); message->SetMessageId(aSeparate ? 0 : aRequest.GetMessageId());
message->SetToken(aRequest.GetToken(), aRequest.GetTokenLength()); message->SetToken(aRequest.GetToken(), aRequest.GetTokenLength());
SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerMessageInfo())); SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerAddress()));
exit: exit:
if (error != OT_ERROR_NONE) if (error != OT_ERROR_NONE)
@@ -436,7 +436,7 @@ bool BorderAgent::HandleUdpReceive(const Message &aMessage, const Ip6::MessageIn
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv))); SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
} }
SuccessOrExit(error = netif.GetCoapSecure().SendMessage(*message, netif.GetCoapSecure().GetPeerMessageInfo())); SuccessOrExit(error = netif.GetCoapSecure().SendMessage(*message, netif.GetCoapSecure().GetPeerAddress()));
otLogInfoMeshCoP("Sent to commissioner on %s", OT_URI_PATH_PROXY_RX); otLogInfoMeshCoP("Sent to commissioner on %s", OT_URI_PATH_PROXY_RX);
@@ -487,7 +487,7 @@ otError BorderAgent::ForwardToCommissioner(Coap::Message &aNewMessage, const Mes
SuccessOrExit(error = aNewMessage.SetLength(offset + aMessage.GetLength() - aMessage.GetOffset())); SuccessOrExit(error = aNewMessage.SetLength(offset + aMessage.GetLength() - aMessage.GetOffset()));
aMessage.CopyTo(aMessage.GetOffset(), offset, aMessage.GetLength() - aMessage.GetOffset(), aNewMessage); aMessage.CopyTo(aMessage.GetOffset(), offset, aMessage.GetLength() - aMessage.GetOffset(), aNewMessage);
SuccessOrExit(error = netif.GetCoapSecure().SendMessage(aNewMessage, netif.GetCoapSecure().GetPeerMessageInfo())); SuccessOrExit(error = netif.GetCoapSecure().SendMessage(aNewMessage, netif.GetCoapSecure().GetPeerAddress()));
otLogInfoMeshCoP("Sent to commissioner"); otLogInfoMeshCoP("Sent to commissioner");
@@ -698,7 +698,7 @@ void BorderAgent::HandleTimeout(void)
otError BorderAgent::Stop(void) otError BorderAgent::Stop(void)
{ {
otError error; otError error = OT_ERROR_NONE;
ThreadNetif & netif = GetNetif(); ThreadNetif & netif = GetNetif();
Coap::CoapSecure &coaps = netif.GetCoapSecure(); Coap::CoapSecure &coaps = netif.GetCoapSecure();
Coap::Coap & coap = netif.GetCoap(); Coap::Coap & coap = netif.GetCoap();
@@ -720,8 +720,7 @@ otError BorderAgent::Stop(void)
coap.RemoveResource(mRelayReceive); coap.RemoveResource(mRelayReceive);
error = coaps.Stop(); coaps.Stop();
assert(error == OT_ERROR_NONE);
SetState(OT_BORDER_AGENT_STATE_STOPPED); SetState(OT_BORDER_AGENT_STATE_STOPPED);
+2 -1
View File
@@ -62,7 +62,8 @@ public:
/** /**
* This method starts the Border Agent service. * This method starts the Border Agent service.
* *
* @retval OT_ERROR_NONE Successfully started the Border Agent service. * @retval OT_ERROR_NONE Successfully started the Border Agent service.
* @retval OT_ERROR_ALREADY Already started.
* *
*/ */
otError Start(void); otError Start(void);
+7 -6
View File
@@ -107,7 +107,7 @@ otError Commissioner::Start(void)
VerifyOrExit(mState == OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_INVALID_STATE); VerifyOrExit(mState == OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
SuccessOrExit(error = GetNetif().GetCoapSecure().Start(OPENTHREAD_CONFIG_JOINER_UDP_PORT, SendRelayTransmit, this)); SuccessOrExit(error = GetNetif().GetCoapSecure().Start(SendRelayTransmit, this));
mState = OT_COMMISSIONER_STATE_PETITION; mState = OT_COMMISSIONER_STATE_PETITION;
mTransmitAttempts = 0; mTransmitAttempts = 0;
@@ -135,7 +135,7 @@ otError Commissioner::Stop(void)
mTimer.Stop(); mTimer.Stop();
GetNetif().GetDtls().Stop(); GetNetif().GetCoapSecure().Stop();
SendKeepAlive(); SendKeepAlive();
@@ -318,7 +318,7 @@ exit:
const char *Commissioner::GetProvisioningUrl(uint16_t &aLength) const const char *Commissioner::GetProvisioningUrl(uint16_t &aLength) const
{ {
ProvisioningUrlTlv &provisioningUrl = GetNetif().GetDtls().mProvisioningUrl; ProvisioningUrlTlv &provisioningUrl = GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl;
aLength = provisioningUrl.GetLength(); aLength = provisioningUrl.GetLength();
@@ -327,7 +327,7 @@ const char *Commissioner::GetProvisioningUrl(uint16_t &aLength) const
otError Commissioner::SetProvisioningUrl(const char *aProvisioningUrl) otError Commissioner::SetProvisioningUrl(const char *aProvisioningUrl)
{ {
return GetNetif().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl); return GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
} }
uint16_t Commissioner::GetSessionId(void) const uint16_t Commissioner::GetSessionId(void) const
@@ -898,8 +898,9 @@ void Commissioner::HandleJoinerFinalize(Coap::Message &aMessage, const Ip6::Mess
if (Tlv::GetTlv(aMessage, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == OT_ERROR_NONE) if (Tlv::GetTlv(aMessage, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == OT_ERROR_NONE)
{ {
if (provisioningUrl.GetLength() != GetNetif().GetDtls().mProvisioningUrl.GetLength() || if (provisioningUrl.GetLength() != GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl.GetLength() ||
memcmp(provisioningUrl.GetProvisioningUrl(), GetNetif().GetDtls().mProvisioningUrl.GetProvisioningUrl(), memcmp(provisioningUrl.GetProvisioningUrl(),
GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl.GetProvisioningUrl(),
provisioningUrl.GetLength()) != 0) provisioningUrl.GetLength()) != 0)
{ {
state = StateTlv::kReject; state = StateTlv::kReject;
+177 -21
View File
@@ -43,6 +43,7 @@
#include "common/encoding.hpp" #include "common/encoding.hpp"
#include "common/instance.hpp" #include "common/instance.hpp"
#include "common/logging.hpp" #include "common/logging.hpp"
#include "common/new.hpp"
#include "common/owner-locator.hpp" #include "common/owner-locator.hpp"
#include "common/timer.hpp" #include "common/timer.hpp"
#include "crypto/sha256.hpp" #include "crypto/sha256.hpp"
@@ -53,7 +54,7 @@
namespace ot { namespace ot {
namespace MeshCoP { namespace MeshCoP {
Dtls::Dtls(Instance &aInstance) Dtls::Dtls(Instance &aInstance, bool aLayerTwoSecurity)
: InstanceLocator(aInstance) : InstanceLocator(aInstance)
, mState(kStateStopped) , mState(kStateStopped)
, mPskLength(0) , mPskLength(0)
@@ -61,6 +62,7 @@ Dtls::Dtls(Instance &aInstance)
, mTimer(aInstance, &Dtls::HandleTimer, this) , mTimer(aInstance, &Dtls::HandleTimer, this)
, mTimerIntermediate(0) , mTimerIntermediate(0)
, mTimerSet(false) , mTimerSet(false)
, mLayerTwoSecurity(aLayerTwoSecurity)
, mReceiveMessage(NULL) , mReceiveMessage(NULL)
, mReceiveOffset(0) , mReceiveOffset(0)
, mReceiveLength(0) , mReceiveLength(0)
@@ -68,6 +70,9 @@ Dtls::Dtls(Instance &aInstance)
, mReceiveHandler(NULL) , mReceiveHandler(NULL)
, mSendHandler(NULL) , mSendHandler(NULL)
, mContext(NULL) , mContext(NULL)
, mSocket(aInstance.GetThreadNetif().GetIp6().GetUdp())
, mTransportCallback(NULL)
, mTransportContext(NULL)
, mMessageSubType(Message::kSubTypeNone) , mMessageSubType(Message::kSubTypeNone)
, mMessageDefaultSubType(Message::kSubTypeNone) , mMessageDefaultSubType(Message::kSubTypeNone)
{ {
@@ -149,11 +154,120 @@ void Dtls::FreeMbedtls(void)
mbedtls_ssl_free(&mSsl); mbedtls_ssl_free(&mSsl);
} }
otError Dtls::Start(bool aClient, otError Dtls::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext)
ConnectedHandler aConnectedHandler, {
ReceiveHandler aReceiveHandler, otError error;
SendHandler aSendHandler,
void * aContext) SuccessOrExit(error = mSocket.Open(&Dtls::HandleUdpReceive, this));
mReceiveHandler = aReceiveHandler;
mConnectedHandler = aConnectedHandler;
mContext = aContext;
exit:
return error;
}
otError Dtls::Connect(const Ip6::SockAddr &aSockAddr)
{
memcpy(&mPeerAddress.mPeerAddr, &aSockAddr.mAddress, sizeof(mPeerAddress.mPeerAddr));
mPeerAddress.mPeerPort = aSockAddr.mPort;
if (aSockAddr.GetAddress().IsLinkLocal() || aSockAddr.GetAddress().IsMulticast())
{
mPeerAddress.mInterfaceId = aSockAddr.mScopeId;
}
else
{
mPeerAddress.mInterfaceId = 0;
}
return Setup(true);
}
void Dtls::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
static_cast<Dtls *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
}
void Dtls::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
ThreadNetif &netif = GetNetif();
if (mState == MeshCoP::Dtls::kStateStopped)
{
Ip6::SockAddr sockAddr;
sockAddr.mAddress = aMessageInfo.GetPeerAddr();
sockAddr.mPort = aMessageInfo.GetPeerPort();
mSocket.Connect(sockAddr);
mPeerAddress.SetPeerAddr(aMessageInfo.GetPeerAddr());
mPeerAddress.SetPeerPort(aMessageInfo.GetPeerPort());
mPeerAddress.SetInterfaceId(aMessageInfo.GetInterfaceId());
if (netif.IsUnicastAddress(aMessageInfo.GetSockAddr()))
{
mPeerAddress.SetSockAddr(aMessageInfo.GetSockAddr());
}
mPeerAddress.SetSockPort(aMessageInfo.GetSockPort());
SuccessOrExit(Setup(false));
}
else
{
// Once DTLS session is started, communicate only with a peer.
VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
(mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()));
}
#if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER
if (mState == MeshCoP::Dtls::kStateConnecting)
{
SetClientId(mPeerAddress.GetPeerAddr().mFields.m8, sizeof(mPeerAddress.GetPeerAddr().mFields));
}
#endif
Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());
exit:
return;
}
otError Dtls::Bind(uint16_t aPort)
{
otError error;
Ip6::SockAddr sockaddr;
VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
sockaddr.mPort = aPort;
SuccessOrExit(error = mSocket.Bind(sockaddr));
mState = kStateStopped;
exit:
return error;
}
otError Dtls::Bind(TransportCallback aCallback, void *aContext)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
mState = kStateStopped;
mTransportCallback = aCallback;
mTransportContext = aContext;
exit:
return error;
}
otError Dtls::Setup(bool aClient)
{ {
int rval; int rval;
@@ -240,12 +354,9 @@ otError Dtls::Start(bool aClient,
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
VerifyOrExit(rval == 0); VerifyOrExit(rval == 0);
mConnectedHandler = aConnectedHandler; mReceiveMessage = NULL;
mReceiveHandler = aReceiveHandler; mMessageSubType = Message::kSubTypeNone;
mSendHandler = aSendHandler; mState = kStateConnecting;
mContext = aContext;
mReceiveMessage = NULL;
mMessageSubType = Message::kSubTypeNone;
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8) if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
{ {
@@ -331,28 +442,37 @@ void Dtls::SetSslAuthMode(bool aVerifyPeerCertificate)
void Dtls::Stop(void) void Dtls::Stop(void)
{ {
VerifyOrExit((mState == kStateConnecting) || (mState == kStateConnected));
mbedtls_ssl_close_notify(&mSsl);
Close(); Close();
exit: mState = kStateStopped;
return; mTransportCallback = NULL;
mTransportContext = NULL;
mTimerSet = false;
mSocket.Close();
mTimer.Stop();
} }
void Dtls::Close(void) void Dtls::Close(void)
{ {
assert((mState == kStateConnecting) || (mState == kStateConnected)); VerifyOrExit(mState == kStateConnecting || mState == kStateConnected);
mbedtls_ssl_close_notify(&mSsl);
mState = kStateCloseNotify; mState = kStateCloseNotify;
mTimer.Start(kGuardTimeNewConnectionMilli); mTimer.Start(kGuardTimeNewConnectionMilli);
FreeMbedtls(); new (&mPeerAddress) Ip6::MessageInfo();
mSocket.Connect(Ip6::SockAddr());
if (mConnectedHandler != NULL) if (mConnectedHandler != NULL)
{ {
mConnectedHandler(mContext, false); mConnectedHandler(mContext, false);
} }
FreeMbedtls();
exit:
return;
} }
otError Dtls::SetPsk(const uint8_t *aPsk, uint8_t aPskLength) otError Dtls::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
@@ -518,7 +638,7 @@ int Dtls::HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength)
} }
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
error = mSendHandler(mContext, aBuf, static_cast<uint16_t>(aLength), mMessageSubType); error = HandleDtlsSend(aBuf, static_cast<uint16_t>(aLength), mMessageSubType);
// Restore default sub type. // Restore default sub type.
mMessageSubType = mMessageDefaultSubType; mMessageSubType = mMessageDefaultSubType;
@@ -691,7 +811,7 @@ int Dtls::HandleMbedtlsExportKeys(const unsigned char *aMasterSecret,
void Dtls::HandleTimer(Timer &aTimer) void Dtls::HandleTimer(Timer &aTimer)
{ {
aTimer.GetOwner<Dtls>().HandleTimer(); static_cast<Dtls *>(static_cast<TimerMilliContext &>(aTimer).GetContext())->HandleTimer();
} }
void Dtls::HandleTimer(void) void Dtls::HandleTimer(void)
@@ -933,6 +1053,42 @@ void Dtls::HandleMbedtlsDebug(void *ctx, int level, const char *, int, const cha
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
} }
otError Dtls::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
{
otError error = OT_ERROR_NONE;
ot::Message *message = NULL;
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
message->SetSubType(aMessageSubType);
message->SetLinkSecurityEnabled(mLayerTwoSecurity);
SuccessOrExit(error = message->Append(aBuf, aLength));
// Set message sub type in case Joiner Finalize Response is appended to the message.
if (aMessageSubType != Message::kSubTypeNone)
{
message->SetSubType(aMessageSubType);
}
if (mTransportCallback)
{
SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mPeerAddress));
}
else
{
SuccessOrExit(error = mSocket.SendTo(*message, mPeerAddress));
}
exit:
if (error != OT_ERROR_NONE && message != NULL)
{
message->Free();
}
return error;
}
} // namespace MeshCoP } // namespace MeshCoP
} // namespace ot } // namespace ot
+123 -17
View File
@@ -60,6 +60,8 @@
#include "common/timer.hpp" #include "common/timer.hpp"
#include "crypto/sha256.hpp" #include "crypto/sha256.hpp"
#include "meshcop/meshcop_tlvs.hpp" #include "meshcop/meshcop_tlvs.hpp"
#include "net/socket.hpp"
#include "net/udp6.hpp"
namespace ot { namespace ot {
@@ -91,10 +93,11 @@ public:
/** /**
* This constructor initializes the DTLS object. * This constructor initializes the DTLS object.
* *
* @param[in] aNetif A reference to the Thread network interface. * @param[in] aNetif A reference to the Thread network interface.
* @param[in] aLayerTwoSecurity Specifies whether to use layer two security or not.
* *
*/ */
explicit Dtls(Instance &aInstance); explicit Dtls(Instance &aInstance, bool aLayerTwoSecurity);
/** /**
* This function pointer is called when a connection is established or torn down. * This function pointer is called when a connection is established or torn down.
@@ -115,6 +118,16 @@ public:
*/ */
typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength); typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength);
/**
* This function pointer is called when secure CoAP server want to send encrypted message.
*
* @param[in] aContext A pointer to arbitrary context information.
* @param[in] aMessage A reference to the message to send.
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
*
*/
typedef otError (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
/** /**
* This function pointer is called when data is ready to transmit for the DTLS session. * This function pointer is called when data is ready to transmit for the DTLS session.
* *
@@ -126,6 +139,19 @@ public:
*/ */
typedef otError (*SendHandler)(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType); typedef otError (*SendHandler)(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
/**
* This method opens the DTLS socket.
*
* @param[in] aReceiveHandler A pointer to a function that is called to receive DTLS payload.
* @param[in] aConnectedHandler A pointer to a function that is called when connected or disconnected.
* @param[in] aContext A pointer to arbitrary context information.
*
* @retval OT_ERROR_NONE Successfully opened the socket.
* @retval OT_ERROR_ALREADY The DTLS is already open.
*
*/
otError Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext);
/** /**
* This method starts the DTLS service. * This method starts the DTLS service.
* *
@@ -133,20 +159,73 @@ public:
* Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or * 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. * set PreShared Key for use DTLS mode PSK with AES 128 CCM 8.
* *
* @param[in] aClient TRUE if operating as a client, FALSE if operating as a server. * @param[in] aSockAddr A reference to the remote sockaddr.
* @param[in] aConnectedHandler A pointer to the connected handler.
* @param[in] aReceiveHandler A pointer to the receive handler.
* @param[in] aSendHandler A pointer to the send handler.
* @param[in] aContext A pointer to application-specific context.
* *
* @retval OT_ERROR_NONE Successfully started the DTLS service. * @retval OT_ERROR_NONE Successfully started the DTLS service.
* *
*/ */
otError Start(bool aClient, otError Connect(const Ip6::SockAddr &aSockAddr);
ConnectedHandler aConnectedHandler,
ReceiveHandler aReceiveHandler, /**
SendHandler aSendHandler, * This method set up the DTLS service.
void * aContext); *
* 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] aClient TRUE if setup for client, otherwise setup for server.
*
* @retval OT_ERROR_NONE Successfully started the DTLS service.
*
*/
otError Setup(bool aClient);
/**
* This method binds this DTLS to a UDP port.
*
* @param[in] aPort The port to bind.
*
* @retval OT_ERROR_NONE Successfully binded the DTLS service.
* @retval OT_ERROR_ALREADY Already bound.
*
*/
otError Bind(uint16_t aPort);
/**
* This method binds this DTLS with a transport callback.
*
* @param[in] aCallback A pointer to a function for sending messages.
* @param[in] aContext A pointer to arbitrary context information.
*
* @retval OT_ERROR_NONE Successfully binded the DTLS service.
* @retval OT_ERROR_ALREADY Already bound.
*
*/
otError Bind(TransportCallback aCallback, void *aContext);
/**
* This method 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) { return mState != kStateStopped; }
/**
* This method 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) { return mState == kStateConnected; }
/**
* This method close the current session.
*
*/
void Close(void);
/** /**
* This method stops the DTLS service. * This method stops the DTLS service.
@@ -308,12 +387,22 @@ public:
*/ */
void SetDefaultMessageSubType(uint8_t aMessageSubType) { mMessageDefaultSubType = aMessageSubType; } void SetDefaultMessageSubType(uint8_t aMessageSubType) { mMessageDefaultSubType = aMessageSubType; }
/**
* This method returns the DTLS session's peer address.
*
* @return DTLS session's message info.
*
*/
const Ip6::MessageInfo &GetPeerAddress(void) const { return mPeerAddress; }
/** /**
* The provisioning URL is placed here so that both the Commissioner and Joiner can share the same object. * The provisioning URL is placed here so that both the Commissioner and Joiner can share the same object.
* *
*/ */
ProvisioningUrlTlv mProvisioningUrl; ProvisioningUrlTlv mProvisioningUrl;
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
private: private:
void FreeMbedtls(void); void FreeMbedtls(void);
@@ -358,9 +447,16 @@ private:
static void HandleTimer(Timer &aTimer); static void HandleTimer(Timer &aTimer);
void HandleTimer(void); void HandleTimer(void);
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleDtlsReceive(const uint8_t *aBuf, uint16_t aLength);
otError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
static void HandleUdpTransmit(Tasklet &aTasklet);
void HandleUdpTransmit(void);
static int HandleMbedtlsEntropyPoll(void *aData, unsigned char *aOutput, size_t aInLen, size_t *aOutLen); static int HandleMbedtlsEntropyPoll(void *aData, unsigned char *aOutput, size_t aInLen, size_t *aOutLen);
void Close(void);
void Process(void); void Process(void);
State mState; State mState;
@@ -402,11 +498,15 @@ private:
mbedtls_ssl_cookie_ctx mCookieCtx; mbedtls_ssl_cookie_ctx mCookieCtx;
#endif #endif
TimerMilli mTimer; TimerMilliContext mTimer;
uint32_t mTimerIntermediate;
bool mTimerSet; uint32_t mTimerIntermediate;
bool mTimerSet : 1;
bool mLayerTwoSecurity : 1;
const Message *mReceiveMessage;
Message *mReceiveMessage;
uint16_t mReceiveOffset; uint16_t mReceiveOffset;
uint16_t mReceiveLength; uint16_t mReceiveLength;
@@ -415,6 +515,12 @@ private:
SendHandler mSendHandler; SendHandler mSendHandler;
void * mContext; void * mContext;
Ip6::MessageInfo mPeerAddress;
Ip6::UdpSocket mSocket;
TransportCallback mTransportCallback;
void * mTransportContext;
uint8_t mMessageSubType; uint8_t mMessageSubType;
uint8_t mMessageDefaultSubType; uint8_t mMessageDefaultSubType;
}; };
+3 -4
View File
@@ -88,7 +88,6 @@ ThreadNetif::ThreadNetif(Instance &aInstance)
, mCommissioner(aInstance) , mCommissioner(aInstance)
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD #endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_DTLS #if OPENTHREAD_ENABLE_DTLS
, mDtls(aInstance)
, mCoapSecure(aInstance) , mCoapSecure(aInstance)
#endif #endif
#if OPENTHREAD_ENABLE_JOINER #if OPENTHREAD_ENABLE_JOINER
@@ -150,14 +149,14 @@ void ThreadNetif::Down(void)
{ {
VerifyOrExit(mIsUp); VerifyOrExit(mIsUp);
#if OPENTHREAD_ENABLE_DTLS
mDtls.Stop();
#endif
#if OPENTHREAD_ENABLE_DNS_CLIENT #if OPENTHREAD_ENABLE_DNS_CLIENT
mDnsClient.Stop(); mDnsClient.Stop();
#endif #endif
#if OPENTHREAD_ENABLE_SNTP_CLIENT #if OPENTHREAD_ENABLE_SNTP_CLIENT
mSntpClient.Stop(); mSntpClient.Stop();
#endif
#if OPENTHREAD_ENABLE_DTLS
mCoapSecure.Stop();
#endif #endif
mCoap.Stop(); mCoap.Stop();
mMleRouter.Disable(); mMleRouter.Disable();
-13
View File
@@ -49,10 +49,6 @@
#include "meshcop/dataset_manager.hpp" #include "meshcop/dataset_manager.hpp"
#if OPENTHREAD_ENABLE_DTLS
#include "meshcop/dtls.hpp"
#endif // OPENTHREAD_ENABLE_DTLS
#if OPENTHREAD_ENABLE_JOINER #if OPENTHREAD_ENABLE_JOINER
#include "meshcop/joiner.hpp" #include "meshcop/joiner.hpp"
#endif // OPENTHREAD_ENABLE_JOINER #endif // OPENTHREAD_ENABLE_JOINER
@@ -341,14 +337,6 @@ public:
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD #endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_DTLS #if OPENTHREAD_ENABLE_DTLS
/**
* This method returns a reference to the Dtls object.
*
* @returns A reference to the Dtls object.
*
*/
MeshCoP::Dtls &GetDtls(void) { return mDtls; }
/** /**
* This method returns a reference to the secure CoAP object. * This method returns a reference to the secure CoAP object.
* *
@@ -491,7 +479,6 @@ private:
#endif // OPENTHREAD_ENABLE_COMMISSIONER #endif // OPENTHREAD_ENABLE_COMMISSIONER
#if OPENTHREAD_ENABLE_DTLS #if OPENTHREAD_ENABLE_DTLS
MeshCoP::Dtls mDtls;
Coap::CoapSecure mCoapSecure; Coap::CoapSecure mCoapSecure;
#endif // OPENTHREAD_ENABLE_DTLS #endif // OPENTHREAD_ENABLE_DTLS