1 /* 2 * Copyright (c) 2018, 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 /** 30 * @file 31 * @brief 32 * This file defines the top-level functions for the OpenThread CoAP Secure implementation. 33 * 34 * @note 35 * The functions in this module require the build-time feature `OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE=1`. 36 * 37 * @note 38 * To enable cipher suite DTLS_PSK_WITH_AES_128_CCM_8, MBEDTLS_KEY_EXCHANGE_PSK_ENABLED 39 * must be enabled in mbedtls-config.h 40 * To enable cipher suite DTLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, 41 * MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED must be enabled in mbedtls-config.h. 42 */ 43 44 #ifndef OPENTHREAD_COAP_SECURE_H_ 45 #define OPENTHREAD_COAP_SECURE_H_ 46 47 #include <stdint.h> 48 49 #include <openthread/coap.h> 50 51 #ifdef __cplusplus 52 extern "C" { 53 #endif 54 55 /** 56 * @addtogroup api-coap-secure 57 * 58 * @brief 59 * This module includes functions that control CoAP Secure (CoAP over DTLS) communication. 60 * 61 * The functions in this module are available when CoAP Secure API feature 62 * (`OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE`) is enabled. 63 * 64 * @{ 65 * 66 */ 67 68 #define OT_DEFAULT_COAP_SECURE_PORT 5684 ///< Default CoAP Secure port, as specified in RFC 7252 69 70 /** 71 * Pointer is called when the DTLS connection state changes. 72 * 73 * @param[in] aConnected true, if a connection was established, false otherwise. 74 * @param[in] aContext A pointer to arbitrary context information. 75 * 76 */ 77 typedef void (*otHandleCoapSecureClientConnect)(bool aConnected, void *aContext); 78 79 /** 80 * Starts the CoAP Secure service. 81 * 82 * @param[in] aInstance A pointer to an OpenThread instance. 83 * @param[in] aPort The local UDP port to bind to. 84 * 85 * @retval OT_ERROR_NONE Successfully started the CoAP Secure server. 86 * 87 */ 88 otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort); 89 90 /** 91 * Stops the CoAP Secure server. 92 * 93 * @param[in] aInstance A pointer to an OpenThread instance. 94 * 95 */ 96 void otCoapSecureStop(otInstance *aInstance); 97 98 /** 99 * Sets the Pre-Shared Key (PSK) and cipher suite 100 * DTLS_PSK_WITH_AES_128_CCM_8. 101 * 102 * @note This function requires the build-time feature `MBEDTLS_KEY_EXCHANGE_PSK_ENABLED` to be enabled. 103 * 104 * @param[in] aInstance A pointer to an OpenThread instance. 105 * @param[in] aPsk A pointer to the PSK. 106 * @param[in] aPskLength The PSK length. 107 * @param[in] aPskIdentity The Identity Name for the PSK. 108 * @param[in] aPskIdLength The PSK Identity Length. 109 * 110 */ 111 void otCoapSecureSetPsk(otInstance *aInstance, 112 const uint8_t *aPsk, 113 uint16_t aPskLength, 114 const uint8_t *aPskIdentity, 115 uint16_t aPskIdLength); 116 117 /** 118 * Returns the peer x509 certificate base64 encoded. 119 * 120 * @note This function requires the build-time features `MBEDTLS_BASE64_C` and 121 * `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled. 122 * 123 * @param[in] aInstance A pointer to an OpenThread instance. 124 * @param[out] aPeerCert A pointer to the base64 encoded certificate buffer. 125 * @param[out] aCertLength The length of the base64 encoded peer certificate. 126 * @param[in] aCertBufferSize The buffer size of aPeerCert. 127 * 128 * @retval OT_ERROR_INVALID_STATE Not connected yet. 129 * @retval OT_ERROR_NONE Successfully get the peer certificate. 130 * @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate. 131 * 132 */ 133 otError otCoapSecureGetPeerCertificateBase64(otInstance *aInstance, 134 unsigned char *aPeerCert, 135 size_t *aCertLength, 136 size_t aCertBufferSize); 137 138 /** 139 * Sets the authentication mode for the coap secure connection. 140 * 141 * Disable or enable the verification of peer certificate. 142 * Must be called before start. 143 * 144 * @param[in] aInstance A pointer to an OpenThread instance. 145 * @param[in] aVerifyPeerCertificate true, to verify the peer certificate. 146 * 147 */ 148 void otCoapSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate); 149 150 /** 151 * Sets the local device's X509 certificate with corresponding private key for 152 * DTLS session with DTLS_ECDHE_ECDSA_WITH_AES_128_CCM_8. 153 * 154 * @note This function requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. 155 * 156 * @param[in] aInstance A pointer to an OpenThread instance. 157 * @param[in] aX509Cert A pointer to the PEM formatted X509 certificate. 158 * @param[in] aX509Length The length of certificate. 159 * @param[in] aPrivateKey A pointer to the PEM formatted private key. 160 * @param[in] aPrivateKeyLength The length of the private key. 161 * 162 */ 163 void otCoapSecureSetCertificate(otInstance *aInstance, 164 const uint8_t *aX509Cert, 165 uint32_t aX509Length, 166 const uint8_t *aPrivateKey, 167 uint32_t aPrivateKeyLength); 168 169 /** 170 * Sets the trusted top level CAs. It is needed for validating the 171 * certificate of the peer. 172 * 173 * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS. 174 * 175 * @note This function requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`. 176 * 177 * @param[in] aInstance A pointer to an OpenThread instance. 178 * @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain. 179 * @param[in] aX509CaCertChainLength The length of chain. 180 * 181 */ 182 void otCoapSecureSetCaCertificateChain(otInstance *aInstance, 183 const uint8_t *aX509CaCertificateChain, 184 uint32_t aX509CaCertChainLength); 185 186 /** 187 * Initializes DTLS session with a peer. 188 * 189 * @param[in] aInstance A pointer to an OpenThread instance. 190 * @param[in] aSockAddr A pointer to the remote socket address. 191 * @param[in] aHandler A pointer to a function that will be called when the DTLS connection 192 * state changes. 193 * @param[in] aContext A pointer to arbitrary context information. 194 * 195 * @retval OT_ERROR_NONE Successfully started DTLS connection. 196 * 197 */ 198 otError otCoapSecureConnect(otInstance *aInstance, 199 const otSockAddr *aSockAddr, 200 otHandleCoapSecureClientConnect aHandler, 201 void *aContext); 202 203 /** 204 * Stops the DTLS connection. 205 * 206 * @param[in] aInstance A pointer to an OpenThread instance. 207 * 208 */ 209 void otCoapSecureDisconnect(otInstance *aInstance); 210 211 /** 212 * Indicates whether or not the DTLS session is connected. 213 * 214 * @param[in] aInstance A pointer to an OpenThread instance. 215 * 216 * @retval TRUE The DTLS session is connected. 217 * @retval FALSE The DTLS session is not connected. 218 * 219 */ 220 bool otCoapSecureIsConnected(otInstance *aInstance); 221 222 /** 223 * Indicates whether or not the DTLS session is active. 224 * 225 * @param[in] aInstance A pointer to an OpenThread instance. 226 * 227 * @retval TRUE If DTLS session is active. 228 * @retval FALSE If DTLS session is not active. 229 * 230 */ 231 bool otCoapSecureIsConnectionActive(otInstance *aInstance); 232 233 /** 234 * Sends a CoAP request block-wise over secure DTLS connection. 235 * 236 * Is available when OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE configuration 237 * is enabled. 238 * 239 * If a response for a request is expected, respective function and context information should be provided. 240 * If no response is expected, these arguments should be NULL pointers. 241 * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message. 242 * 243 * @param[in] aInstance A pointer to an OpenThread instance. 244 * @param[in] aMessage A reference to the message to send. 245 * @param[in] aHandler A function pointer that shall be called on response reception or time-out. 246 * @param[in] aContext A pointer to arbitrary context information. 247 * @param[in] aTransmitHook A function pointer that is called on Block1 response reception. 248 * @param[in] aReceiveHook A function pointer that is called on Block2 response reception. 249 * 250 * @retval OT_ERROR_NONE Successfully sent CoAP message. 251 * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. 252 * @retval OT_ERROR_INVALID_STATE DTLS connection was not initialized. 253 * 254 */ 255 otError otCoapSecureSendRequestBlockWise(otInstance *aInstance, 256 otMessage *aMessage, 257 otCoapResponseHandler aHandler, 258 void *aContext, 259 otCoapBlockwiseTransmitHook aTransmitHook, 260 otCoapBlockwiseReceiveHook aReceiveHook); 261 262 /** 263 * Sends a CoAP request over secure DTLS connection. 264 * 265 * If a response for a request is expected, respective function and context information should be provided. 266 * If no response is expected, these arguments should be NULL pointers. 267 * If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message. 268 * 269 * @param[in] aInstance A pointer to an OpenThread instance. 270 * @param[in] aMessage A reference to the message to send. 271 * @param[in] aHandler A function pointer that shall be called on response reception or time-out. 272 * @param[in] aContext A pointer to arbitrary context information. 273 * 274 * @retval OT_ERROR_NONE Successfully sent CoAP message. 275 * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. 276 * @retval OT_ERROR_INVALID_STATE DTLS connection was not initialized. 277 * 278 */ 279 otError otCoapSecureSendRequest(otInstance *aInstance, 280 otMessage *aMessage, 281 otCoapResponseHandler aHandler, 282 void *aContext); 283 284 /** 285 * Adds a resource to the CoAP Secure server. 286 * 287 * @param[in] aInstance A pointer to an OpenThread instance. 288 * @param[in] aResource A pointer to the resource. 289 * 290 */ 291 void otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource); 292 293 /** 294 * Removes a resource from the CoAP Secure server. 295 * 296 * @param[in] aInstance A pointer to an OpenThread instance. 297 * @param[in] aResource A pointer to the resource. 298 * 299 */ 300 void otCoapSecureRemoveResource(otInstance *aInstance, otCoapResource *aResource); 301 302 /** 303 * Adds a block-wise resource to the CoAP Secure server. 304 * 305 * @param[in] aInstance A pointer to an OpenThread instance. 306 * @param[in] aResource A pointer to the resource. 307 * 308 */ 309 void otCoapSecureAddBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource); 310 311 /** 312 * Removes a block-wise resource from the CoAP Secure server. 313 * 314 * @param[in] aInstance A pointer to an OpenThread instance. 315 * @param[in] aResource A pointer to the resource. 316 * 317 */ 318 void otCoapSecureRemoveBlockWiseResource(otInstance *aInstance, otCoapBlockwiseResource *aResource); 319 320 /** 321 * Sets the default handler for unhandled CoAP Secure requests. 322 * 323 * @param[in] aInstance A pointer to an OpenThread instance. 324 * @param[in] aHandler A function pointer that shall be called when an unhandled request arrives. 325 * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. 326 * 327 */ 328 void otCoapSecureSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext); 329 330 /** 331 * Sets the connected callback to indicate, when 332 * a Client connect to the CoAP Secure server. 333 * 334 * @param[in] aInstance A pointer to an OpenThread instance. 335 * @param[in] aHandler A pointer to a function that will be called once DTLS connection is established. 336 * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. 337 * 338 */ 339 void otCoapSecureSetClientConnectedCallback(otInstance *aInstance, 340 otHandleCoapSecureClientConnect aHandler, 341 void *aContext); 342 343 /** 344 * Sends a CoAP response block-wise from the CoAP Secure server. 345 * 346 * Is available when OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE configuration 347 * is enabled. 348 * 349 * @param[in] aInstance A pointer to an OpenThread instance. 350 * @param[in] aMessage A pointer to the CoAP response to send. 351 * @param[in] aMessageInfo A pointer to the message info associated with @p aMessage. 352 * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. 353 * @param[in] aTransmitHook A function pointer that is called on Block1 request reception. 354 * 355 * @retval OT_ERROR_NONE Successfully enqueued the CoAP response message. 356 * @retval OT_ERROR_NO_BUFS Insufficient buffers available to send the CoAP response. 357 * 358 */ 359 otError otCoapSecureSendResponseBlockWise(otInstance *aInstance, 360 otMessage *aMessage, 361 const otMessageInfo *aMessageInfo, 362 void *aContext, 363 otCoapBlockwiseTransmitHook aTransmitHook); 364 365 /** 366 * Sends a CoAP response from the CoAP Secure server. 367 * 368 * @param[in] aInstance A pointer to an OpenThread instance. 369 * @param[in] aMessage A pointer to the CoAP response to send. 370 * @param[in] aMessageInfo A pointer to the message info associated with @p aMessage. 371 * 372 * @retval OT_ERROR_NONE Successfully enqueued the CoAP response message. 373 * @retval OT_ERROR_NO_BUFS Insufficient buffers available to send the CoAP response. 374 * 375 */ 376 otError otCoapSecureSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo); 377 378 /** 379 * @} 380 * 381 */ 382 383 #ifdef __cplusplus 384 } // extern "C" 385 #endif 386 387 #endif /* OPENTHREAD_COAP_SECURE_H_ */ 388