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 /** 30 * @file 31 * This file includes definitions for using mbedTLS. 32 */ 33 34 #ifndef DTLS_HPP_ 35 #define DTLS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <mbedtls/net_sockets.h> 40 #include <mbedtls/ssl.h> 41 #include <mbedtls/ssl_cookie.h> 42 #include <mbedtls/version.h> 43 44 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 45 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 46 #include <mbedtls/base64.h> 47 #endif 48 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED 49 #include <mbedtls/x509.h> 50 #include <mbedtls/x509_crl.h> 51 #include <mbedtls/x509_crt.h> 52 #include <mbedtls/x509_csr.h> 53 #endif 54 #endif 55 56 #include "common/callback.hpp" 57 #include "common/locator.hpp" 58 #include "common/message.hpp" 59 #include "common/random.hpp" 60 #include "common/timer.hpp" 61 #include "crypto/sha256.hpp" 62 #include "meshcop/meshcop_tlvs.hpp" 63 #include "net/socket.hpp" 64 #include "net/udp6.hpp" 65 66 namespace ot { 67 68 namespace MeshCoP { 69 70 class Dtls : public InstanceLocator 71 { 72 public: 73 static constexpr uint8_t kPskMaxLength = 32; ///< Maximum PSK length. 74 75 /** 76 * Initializes the DTLS object. 77 * 78 * @param[in] aInstance A reference to the OpenThread instance. 79 * @param[in] aLayerTwoSecurity Specifies whether to use layer two security or not. 80 * 81 */ 82 explicit Dtls(Instance &aInstance, bool aLayerTwoSecurity); 83 84 /** 85 * Pointer is called when a connection is established or torn down. 86 * 87 * @param[in] aContext A pointer to application-specific context. 88 * @param[in] aConnected TRUE if a connection was established, FALSE otherwise. 89 * 90 */ 91 typedef void (*ConnectedHandler)(void *aContext, bool aConnected); 92 93 /** 94 * Pointer is called when data is received from the DTLS session. 95 * 96 * @param[in] aContext A pointer to application-specific context. 97 * @param[in] aBuf A pointer to the received data buffer. 98 * @param[in] aLength Number of bytes in the received data buffer. 99 * 100 */ 101 typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength); 102 103 /** 104 * Pointer is called when secure CoAP server want to send encrypted message. 105 * 106 * @param[in] aContext A pointer to arbitrary context information. 107 * @param[in] aMessage A reference to the message to send. 108 * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. 109 * 110 */ 111 typedef Error (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 112 113 /** 114 * Opens the DTLS socket. 115 * 116 * @param[in] aReceiveHandler A pointer to a function that is called to receive DTLS payload. 117 * @param[in] aConnectedHandler A pointer to a function that is called when connected or disconnected. 118 * @param[in] aContext A pointer to arbitrary context information. 119 * 120 * @retval kErrorNone Successfully opened the socket. 121 * @retval kErrorAlready The DTLS is already open. 122 * 123 */ 124 Error Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext); 125 126 /** 127 * Binds this DTLS to a UDP port. 128 * 129 * @param[in] aPort The port to bind. 130 * 131 * @retval kErrorNone Successfully bound the DTLS socket. 132 * @retval kErrorInvalidState The DTLS socket is not open. 133 * @retval kErrorAlready Already bound. 134 * 135 */ 136 Error Bind(uint16_t aPort); 137 138 /** 139 * Gets the UDP port of this session. 140 * 141 * @returns UDP port number. 142 * 143 */ 144 uint16_t GetUdpPort(void) const; 145 146 /** 147 * Binds this DTLS with a transport callback. 148 * 149 * @param[in] aCallback A pointer to a function for sending messages. 150 * @param[in] aContext A pointer to arbitrary context information. 151 * 152 * @retval kErrorNone Successfully bound the DTLS socket. 153 * @retval kErrorInvalidState The DTLS socket is not open. 154 * @retval kErrorAlready Already bound. 155 * 156 */ 157 Error Bind(TransportCallback aCallback, void *aContext); 158 159 /** 160 * Establishes a DTLS session. 161 * 162 * For CoAP Secure API do first: 163 * Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or 164 * set PreShared Key for use DTLS mode PSK with AES 128 CCM 8. 165 * 166 * @param[in] aSockAddr A reference to the remote sockaddr. 167 * 168 * @retval kErrorNone Successfully started DTLS handshake. 169 * @retval kErrorInvalidState The DTLS socket is not open. 170 * 171 */ 172 Error Connect(const Ip6::SockAddr &aSockAddr); 173 174 /** 175 * Indicates whether or not the DTLS session is active. 176 * 177 * @retval TRUE If DTLS session is active. 178 * @retval FALSE If DTLS session is not active. 179 * 180 */ IsConnectionActive(void) const181 bool IsConnectionActive(void) const { return mState >= kStateConnecting; } 182 183 /** 184 * Indicates whether or not the DTLS session is connected. 185 * 186 * @retval TRUE The DTLS session is connected. 187 * @retval FALSE The DTLS session is not connected. 188 * 189 */ IsConnected(void) const190 bool IsConnected(void) const { return mState == kStateConnected; } 191 192 /** 193 * Disconnects the DTLS session. 194 * 195 */ 196 void Disconnect(void); 197 198 /** 199 * Closes the DTLS socket. 200 * 201 */ 202 void Close(void); 203 204 /** 205 * Sets the PSK. 206 * 207 * @param[in] aPsk A pointer to the PSK. 208 * 209 * @retval kErrorNone Successfully set the PSK. 210 * @retval kErrorInvalidArgs The PSK is invalid. 211 * 212 */ 213 Error SetPsk(const uint8_t *aPsk, uint8_t aPskLength); 214 215 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 216 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED 217 /** 218 * Sets the Pre-Shared Key (PSK) for DTLS sessions- 219 * identified by a PSK. 220 * 221 * DTLS mode "PSK with AES 128 CCM 8" for Application CoAPS. 222 * 223 * @param[in] aPsk A pointer to the PSK. 224 * @param[in] aPskLength The PSK char length. 225 * @param[in] aPskIdentity The Identity Name for the PSK. 226 * @param[in] aPskIdLength The PSK Identity Length. 227 * 228 * @retval kErrorNone Successfully set the PSK. 229 * 230 */ 231 void SetPreSharedKey(const uint8_t *aPsk, uint16_t aPskLength, const uint8_t *aPskIdentity, uint16_t aPskIdLength); 232 233 #endif 234 235 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED 236 /** 237 * Sets a reference to the own x509 certificate with corresponding private key. 238 * 239 * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS. 240 * 241 * @param[in] aX509Certificate A pointer to the PEM formatted X509 certificate. 242 * @param[in] aX509CertLength The length of certificate. 243 * @param[in] aPrivateKey A pointer to the PEM formatted private key. 244 * @param[in] aPrivateKeyLength The length of the private key. 245 * 246 */ 247 void SetCertificate(const uint8_t *aX509Certificate, 248 uint32_t aX509CertLength, 249 const uint8_t *aPrivateKey, 250 uint32_t aPrivateKeyLength); 251 252 /** 253 * Sets the trusted top level CAs. It is needed for validate the 254 * certificate of the peer. 255 * 256 * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS. 257 * 258 * @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain. 259 * @param[in] aX509CaCertChainLength The length of chain. 260 * 261 */ 262 void SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength); 263 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED 264 265 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 266 /** 267 * Returns the peer x509 certificate base64 encoded. 268 * 269 * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS. 270 * 271 * @param[out] aPeerCert A pointer to the base64 encoded certificate buffer. 272 * @param[out] aCertLength The length of the base64 encoded peer certificate. 273 * @param[in] aCertBufferSize The buffer size of aPeerCert. 274 * 275 * @retval kErrorInvalidState Not connected yet. 276 * @retval kErrorNone Successfully get the peer certificate. 277 * @retval kErrorNoBufs Can't allocate memory for certificate. 278 * 279 */ 280 Error GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize); 281 #endif // defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 282 283 /** 284 * Set the authentication mode for a dtls connection. 285 * 286 * Disable or enable the verification of peer certificate. 287 * Must called before start. 288 * 289 * @param[in] aVerifyPeerCertificate true, if the peer certificate should verify. 290 * 291 */ SetSslAuthMode(bool aVerifyPeerCertificate)292 void SetSslAuthMode(bool aVerifyPeerCertificate) { mVerifyPeerCertificate = aVerifyPeerCertificate; } 293 #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 294 295 #ifdef MBEDTLS_SSL_SRV_C 296 /** 297 * Sets the Client ID used for generating the Hello Cookie. 298 * 299 * @param[in] aClientId A pointer to the Client ID. 300 * @param[in] aLength Number of bytes in the Client ID. 301 * 302 * @retval kErrorNone Successfully set the Client ID. 303 * 304 */ 305 Error SetClientId(const uint8_t *aClientId, uint8_t aLength); 306 #endif 307 308 /** 309 * Sends data within the DTLS session. 310 * 311 * @param[in] aMessage A message to send via DTLS. 312 * @param[in] aLength Number of bytes in the data buffer. 313 * 314 * @retval kErrorNone Successfully sent the data via the DTLS session. 315 * @retval kErrorNoBufs A message is too long. 316 * 317 */ 318 Error Send(Message &aMessage, uint16_t aLength); 319 320 /** 321 * Provides a received DTLS message to the DTLS object. 322 * 323 * @param[in] aMessage A reference to the message. 324 * 325 */ 326 void Receive(Message &aMessage); 327 328 /** 329 * Sets the default message sub-type that will be used for all messages without defined 330 * sub-type. 331 * 332 * @param[in] aMessageSubType The default message sub-type. 333 * 334 */ SetDefaultMessageSubType(Message::SubType aMessageSubType)335 void SetDefaultMessageSubType(Message::SubType aMessageSubType) { mMessageDefaultSubType = aMessageSubType; } 336 337 /** 338 * Returns the DTLS session's peer address. 339 * 340 * @return DTLS session's message info. 341 * 342 */ GetMessageInfo(void) const343 const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; } 344 345 void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 346 347 private: 348 enum State : uint8_t 349 { 350 kStateClosed, // UDP socket is closed. 351 kStateOpen, // UDP socket is open. 352 kStateInitializing, // The DTLS service is initializing. 353 kStateConnecting, // The DTLS service is establishing a connection. 354 kStateConnected, // The DTLS service has a connection established. 355 kStateCloseNotify, // The DTLS service is closing a connection. 356 }; 357 358 static constexpr uint32_t kGuardTimeNewConnectionMilli = 2000; 359 360 #if !OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 361 static constexpr uint16_t kApplicationDataMaxLength = 1152; 362 #else 363 static constexpr uint16_t kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH; 364 #endif 365 366 static constexpr size_t kDtlsKeyBlockSize = 40; 367 static constexpr size_t kDtlsRandomBufferSize = 32; 368 369 void FreeMbedtls(void); 370 Error Setup(bool aClient); 371 372 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 373 /** 374 * Set keys and/or certificates for dtls session dependent of used cipher suite. 375 * 376 * @retval mbedtls error, 0 if successfully. 377 * 378 */ 379 int SetApplicationCoapSecureKeys(void); 380 #endif 381 382 static void HandleMbedtlsDebug(void *aContext, int aLevel, const char *aFile, int aLine, const char *aStr); 383 void HandleMbedtlsDebug(int aLevel, const char *aFile, int aLine, const char *aStr); 384 385 static int HandleMbedtlsGetTimer(void *aContext); 386 int HandleMbedtlsGetTimer(void); 387 388 static void HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish); 389 void HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish); 390 391 static int HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength); 392 int HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength); 393 394 static int HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength); 395 int HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength); 396 397 #ifdef MBEDTLS_SSL_EXPORT_KEYS 398 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000) 399 400 static void HandleMbedtlsExportKeys(void *aContext, 401 mbedtls_ssl_key_export_type aType, 402 const unsigned char *aMasterSecret, 403 size_t aMasterSecretLen, 404 const unsigned char aClientRandom[32], 405 const unsigned char aServerRandom[32], 406 mbedtls_tls_prf_types aTlsPrfType); 407 408 void HandleMbedtlsExportKeys(mbedtls_ssl_key_export_type aType, 409 const unsigned char *aMasterSecret, 410 size_t aMasterSecretLen, 411 const unsigned char aClientRandom[32], 412 const unsigned char aServerRandom[32], 413 mbedtls_tls_prf_types aTlsPrfType); 414 415 #else 416 417 static int HandleMbedtlsExportKeys(void *aContext, 418 const unsigned char *aMasterSecret, 419 const unsigned char *aKeyBlock, 420 size_t aMacLength, 421 size_t aKeyLength, 422 size_t aIvLength); 423 int HandleMbedtlsExportKeys(const unsigned char *aMasterSecret, 424 const unsigned char *aKeyBlock, 425 size_t aMacLength, 426 size_t aKeyLength, 427 size_t aIvLength); 428 429 #endif // (MBEDTLS_VERSION_NUMBER >= 0x03000000) 430 #endif // MBEDTLS_SSL_EXPORT_KEYS 431 432 static void HandleTimer(Timer &aTimer); 433 void HandleTimer(void); 434 435 static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); 436 437 void HandleDtlsReceive(const uint8_t *aBuf, uint16_t aLength); 438 Error HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, Message::SubType aMessageSubType); 439 440 void Process(void); 441 442 State mState; 443 444 int mCipherSuites[2]; 445 uint8_t mPsk[kPskMaxLength]; 446 uint8_t mPskLength; 447 448 #if (MBEDTLS_VERSION_NUMBER >= 0x03010000) 449 static const uint16_t sGroups[]; 450 #else 451 static const mbedtls_ecp_group_id sCurves[]; 452 #endif 453 454 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) || defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) 455 #if (MBEDTLS_VERSION_NUMBER >= 0x03020000) 456 static const uint16_t sSignatures[]; 457 #else 458 static const int sHashes[]; 459 #endif 460 #endif 461 462 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 463 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED 464 const uint8_t *mCaChainSrc; 465 uint32_t mCaChainLength; 466 const uint8_t *mOwnCertSrc; 467 uint32_t mOwnCertLength; 468 const uint8_t *mPrivateKeySrc; 469 uint32_t mPrivateKeyLength; 470 mbedtls_x509_crt mCaChain; 471 mbedtls_x509_crt mOwnCert; 472 mbedtls_pk_context mPrivateKey; 473 #endif 474 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED 475 const uint8_t *mPreSharedKey; 476 const uint8_t *mPreSharedKeyIdentity; 477 uint16_t mPreSharedKeyLength; 478 uint16_t mPreSharedKeyIdLength; 479 #endif 480 #endif 481 482 bool mVerifyPeerCertificate; 483 484 mbedtls_ssl_context mSsl; 485 mbedtls_ssl_config mConf; 486 487 #ifdef MBEDTLS_SSL_COOKIE_C 488 mbedtls_ssl_cookie_ctx mCookieCtx; 489 #endif 490 491 TimerMilliContext mTimer; 492 493 TimeMilli mTimerIntermediate; 494 bool mTimerSet : 1; 495 496 bool mLayerTwoSecurity : 1; 497 498 Message *mReceiveMessage; 499 500 Callback<ConnectedHandler> mConnectedCallback; 501 Callback<ReceiveHandler> mReceiveCallback; 502 503 Ip6::MessageInfo mMessageInfo; 504 Ip6::Udp::Socket mSocket; 505 506 Callback<TransportCallback> mTransportCallback; 507 508 Message::SubType mMessageSubType; 509 Message::SubType mMessageDefaultSubType; 510 }; 511 512 } // namespace MeshCoP 513 } // namespace ot 514 515 #endif // DTLS_HPP_ 516