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