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