• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef COAP_SECURE_HPP_
30 #define COAP_SECURE_HPP_
31 
32 #include "openthread-core-config.h"
33 
34 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE && !OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE
35 #error "CoAP Secure API feature requires `OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE`"
36 #endif
37 
38 #if OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE
39 
40 #include "coap/coap.hpp"
41 #include "common/callback.hpp"
42 #include "meshcop/meshcop.hpp"
43 #include "meshcop/secure_transport.hpp"
44 
45 #include <openthread/coap_secure.h>
46 
47 /**
48  * @file
49  *   This file includes definitions for the secure CoAP.
50  */
51 
52 namespace ot {
53 namespace Coap {
54 
55 typedef MeshCoP::Dtls Dtls;
56 
57 /**
58  * Represents a secure CoAP session.
59  */
60 class SecureSession : public CoapBase, public Dtls::Session
61 {
62 public:
63     /**
64      * Dequeues and frees all queued messages (requests and responses) and stops all timers and tasklets.
65      */
66     void Cleanup(void);
67 
68     /**
69      * Sets the connection event callback.
70      *
71      * @param[in]  aHandler   A pointer to a function that is called when connected or disconnected.
72      * @param[in]  aContext   A pointer to arbitrary context information.
73      */
SetConnectCallback(ConnectHandler aHandler,void * aContext)74     void SetConnectCallback(ConnectHandler aHandler, void *aContext) { mConnectCallback.Set(aHandler, aContext); }
75 
76 #if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
77     /**
78      * Sends a CoAP message over secure DTLS session.
79      *
80      * If a response for a request is expected, respective function and context information should be provided.
81      * If no response is expected, these arguments should be NULL pointers.
82      * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
83      *
84      * @param[in]  aMessage      A reference to the message to send.
85      * @param[in]  aHandler      A function pointer that shall be called on response reception or time-out.
86      * @param[in]  aContext      A pointer to arbitrary context information.
87      * @param[in]  aTransmitHook A pointer to a hook function for outgoing block-wise transfer.
88      * @param[in]  aReceiveHook  A pointer to a hook function for incoming block-wise transfer.
89      *
90      * @retval kErrorNone          Successfully sent CoAP message.
91      * @retval kErrorNoBufs        Failed to allocate retransmission data.
92      * @retval kErrorInvalidState  DTLS connection was not initialized.
93      */
94     Error SendMessage(Message                    &aMessage,
95                       ResponseHandler             aHandler      = nullptr,
96                       void                       *aContext      = nullptr,
97                       otCoapBlockwiseTransmitHook aTransmitHook = nullptr,
98                       otCoapBlockwiseReceiveHook  aReceiveHook  = nullptr);
99 
100 #else
101     /**
102      * Sends a CoAP message over secure DTLS session.
103      *
104      * If a response for a request is expected, respective function and context information should be provided.
105      * If no response is expected, these arguments should be nullptr pointers.
106      * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
107      *
108      * @param[in]  aMessage      A reference to the message to send.
109      * @param[in]  aHandler      A function pointer that shall be called on response reception or time-out.
110      * @param[in]  aContext      A pointer to arbitrary context information.
111      *
112      * @retval kErrorNone          Successfully sent CoAP message.
113      * @retval kErrorNoBufs        Failed to allocate retransmission data.
114      * @retval kErrorInvalidState  DTLS connection was not initialized.
115      */
116     Error SendMessage(Message &aMessage, ResponseHandler aHandler = nullptr, void *aContext = nullptr);
117 #endif
118 
119 protected:
120     SecureSession(Instance &aInstance, Dtls::Transport &aDtlsTransport);
121 
122 private:
123     static Error Transmit(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
124     Error        Transmit(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
125     static void  HandleTransmitTask(Tasklet &aTasklet);
126     void         HandleTransmitTask(void);
127     static void  HandleDtlsConnectEvent(ConnectEvent aEvent, void *aContext);
128     void         HandleDtlsConnectEvent(ConnectEvent aEvent);
129     static void  HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength);
130     void         HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength);
131 
132     Callback<ConnectHandler> mConnectCallback;
133     ot::MessageQueue         mTransmitQueue;
134     TaskletContext           mTransmitTask;
135 };
136 
137 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
138 
139 /**
140  * Represents an Application CoAPS.
141  */
142 class ApplicationCoapSecure : public Dtls::Transport, public Dtls::Transport::Extension, public SecureSession
143 {
144 public:
145     /**
146      * Initializes the `ApplicationCoapSecure`
147      *
148      * @param[in]  aInstance           A reference to the OpenThread instance.
149      * @param[in]  aLayerTwoSecurity   Specifies whether to use layer two security or not.
150      */
ApplicationCoapSecure(Instance & aInstance,LinkSecurityMode aLayerTwoSecurity)151     ApplicationCoapSecure(Instance &aInstance, LinkSecurityMode aLayerTwoSecurity)
152         : Dtls::Transport(aInstance, aLayerTwoSecurity)
153         , Dtls::Transport::Extension(static_cast<Dtls::Transport &>(*this))
154         , SecureSession(aInstance, static_cast<Dtls::Transport &>(*this))
155     {
156         Dtls::Transport::SetAcceptCallback(HandleDtlsAccept, this);
157         Dtls::Transport::SetExtension(static_cast<Dtls::Transport::Extension &>(*this));
158     }
159 
160 private:
161     static MeshCoP::SecureSession *HandleDtlsAccept(void *aContext, const Ip6::MessageInfo &aMessageInfo);
162     SecureSession                 *HandleDtlsAccept(void);
163 };
164 
165 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
166 
167 } // namespace Coap
168 } // namespace ot
169 
170 #endif // OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE
171 
172 #endif // COAP_SECURE_HPP_
173