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