• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SECURE_TRANSPORT_HPP_
35 #define SECURE_TRANSPORT_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #ifdef OPENTHREAD_CONFIG_TLS_API_ENABLE
40 #error `OPENTHREAD_CONFIG_TLS_API_ENABLE` must not be defined directly, it is determined from `COAP_SECURE_API_ENABLE` and `BLE_TCAT_ENABLE`
41 #endif
42 
43 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE || OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
44 #define OPENTHREAD_CONFIG_TLS_API_ENABLE 1
45 #else
46 #define OPENTHREAD_CONFIG_TLS_API_ENABLE 0
47 #endif
48 
49 #include <mbedtls/net_sockets.h>
50 #include <mbedtls/ssl.h>
51 #include <mbedtls/ssl_cookie.h>
52 #include <mbedtls/version.h>
53 
54 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
55 #ifndef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
56 #error OPENTHREAD_CONFIG_BLE_TCAT_ENABLE requires MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
57 #endif
58 #endif
59 
60 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
61 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
62 #include <mbedtls/base64.h>
63 #endif
64 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
65 #include <mbedtls/x509.h>
66 #include <mbedtls/x509_crl.h>
67 #include <mbedtls/x509_crt.h>
68 #include <mbedtls/x509_csr.h>
69 #endif
70 #endif
71 
72 #include "common/callback.hpp"
73 #include "common/locator.hpp"
74 #include "common/log.hpp"
75 #include "common/message.hpp"
76 #include "common/random.hpp"
77 #include "common/timer.hpp"
78 #include "crypto/sha256.hpp"
79 #include "meshcop/meshcop_tlvs.hpp"
80 #include "net/socket.hpp"
81 #include "net/udp6.hpp"
82 
83 namespace ot {
84 
85 namespace MeshCoP {
86 
87 class SecureTransport : public InstanceLocator
88 {
89 public:
90     static constexpr uint8_t kPskMaxLength = 32; ///< Maximum PSK length.
91 
92     /**
93      * Initializes the SecureTransport object.
94      *
95      * @param[in]  aInstance            A reference to the OpenThread instance.
96      * @param[in]  aLayerTwoSecurity    Specifies whether to use layer two security or not.
97      * @param[in]  aDatagramTransport   Specifies if dtls of tls connection should be used.
98      *
99      */
100     explicit SecureTransport(Instance &aInstance, bool aLayerTwoSecurity, bool aDatagramTransport = true);
101 
102     /**
103      * Pointer is called when a connection is established or torn down.
104      *
105      * @param[in]  aContext    A pointer to application-specific context.
106      * @param[in]  aConnected  TRUE if a connection was established, FALSE otherwise.
107      *
108      */
109     typedef void (*ConnectedHandler)(void *aContext, bool aConnected);
110 
111     /**
112      * Pointer is called when data is received from the session.
113      *
114      * @param[in]  aContext  A pointer to application-specific context.
115      * @param[in]  aBuf      A pointer to the received data buffer.
116      * @param[in]  aLength   Number of bytes in the received data buffer.
117      *
118      */
119     typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength);
120 
121     /**
122      * Pointer is called when secure CoAP server want to send encrypted message.
123      *
124      * @param[in]  aContext      A pointer to arbitrary context information.
125      * @param[in]  aMessage      A reference to the message to send.
126      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
127      *
128      */
129     typedef Error (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
130 
131     /**
132      * Callback to notify when the socket is automatically closed due to reaching the maximum number of connection
133      * attempts (set from `SetMaxConnectionAttempts()`).
134      *
135      * @param[in] aContext    A pointer to arbitrary context information.
136      *
137      */
138     typedef void (*AutoCloseCallback)(void *aContext);
139 
140     /**
141      * Opens the socket.
142      *
143      * @param[in]  aReceiveHandler      A pointer to a function that is called to receive payload.
144      * @param[in]  aConnectedHandler    A pointer to a function that is called when connected or disconnected.
145      * @param[in]  aContext             A pointer to arbitrary context information.
146      *
147      * @retval kErrorNone     Successfully opened the socket.
148      * @retval kErrorAlready  The connection is already open.
149      *
150      */
151     Error Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext);
152 
153     /**
154      * Sets the maximum number of allowed connection requests before socket is automatically closed.
155      *
156      * This method can be called when socket is closed. Otherwise `kErrorInvalidSatet` is returned.
157      *
158      * If @p aMaxAttempts is zero, no limit is applied and connections are allowed until the socket is closed. This is
159      * the default behavior if `SetMaxConnectionAttempts()` is not called.
160      *
161      * @param[in] aMaxAttempts    Maximum number of allowed connection attempts.
162      * @param[in] aCallback       Callback to notify when max number of attempts has reached and socket is closed.
163      * @param[in] aContext        A pointer to arbitrary context to use with `AutoCloseCallback`.
164      *
165      * @retval kErrorNone          Successfully set the maximum allowed connection attempts and callback.
166      * @retval kErrorInvalidState  Socket is not closed.
167      *
168      */
169     Error SetMaxConnectionAttempts(uint16_t aMaxAttempts, AutoCloseCallback aCallback, void *aContext);
170 
171     /**
172      * Binds this DTLS to a UDP port.
173      *
174      * @param[in]  aPort              The port to bind.
175      *
176      * @retval kErrorNone           Successfully bound the socket.
177      * @retval kErrorInvalidState   The socket is not open.
178      * @retval kErrorAlready        Already bound.
179      *
180      */
181     Error Bind(uint16_t aPort);
182 
183     /**
184      * Gets the UDP port of this session.
185      *
186      * @returns  UDP port number.
187      *
188      */
189     uint16_t GetUdpPort(void) const;
190 
191     /**
192      * Binds with a transport callback.
193      *
194      * @param[in]  aCallback  A pointer to a function for sending messages.
195      * @param[in]  aContext   A pointer to arbitrary context information.
196      *
197      * @retval kErrorNone           Successfully bound the socket.
198      * @retval kErrorInvalidState   The socket is not open.
199      * @retval kErrorAlready        Already bound.
200      *
201      */
202     Error Bind(TransportCallback aCallback, void *aContext);
203 
204     /**
205      * Establishes a secure session.
206      *
207      * For CoAP Secure API do first:
208      * Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or
209      * set PreShared Key for use DTLS mode PSK with AES 128 CCM 8.
210      *
211      * @param[in]  aSockAddr               A reference to the remote sockaddr.
212      *
213      * @retval kErrorNone          Successfully started handshake.
214      * @retval kErrorInvalidState  The socket is not open.
215      *
216      */
217     Error Connect(const Ip6::SockAddr &aSockAddr);
218 
219     /**
220      * Indicates whether or not the session is active.
221      *
222      * @retval TRUE  If session is active.
223      * @retval FALSE If session is not active.
224      *
225      */
IsConnectionActive(void) const226     bool IsConnectionActive(void) const { return mState >= kStateConnecting; }
227 
228     /**
229      * Indicates whether or not the session is connected.
230      *
231      * @retval TRUE   The session is connected.
232      * @retval FALSE  The session is not connected.
233      *
234      */
IsConnected(void) const235     bool IsConnected(void) const { return mState == kStateConnected; }
236 
237     /**
238      * Indicates whether or not the session is closed.
239      *
240      * @retval TRUE   The session is closed.
241      * @retval FALSE  The session is not closed.
242      *
243      */
IsClosed(void) const244     bool IsClosed(void) const { return mState == kStateClosed; }
245 
246     /**
247      * Disconnects the session.
248      *
249      */
250     void Disconnect(void);
251 
252     /**
253      * Closes the socket.
254      *
255      */
256     void Close(void);
257 
258     /**
259      * Sets the PSK.
260      *
261      * @param[in]  aPsk  A pointer to the PSK.
262      *
263      * @retval kErrorNone          Successfully set the PSK.
264      * @retval kErrorInvalidArgs   The PSK is invalid.
265      *
266      */
267     Error SetPsk(const uint8_t *aPsk, uint8_t aPskLength);
268 
269 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
270 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
271     /**
272      * Sets the Pre-Shared Key (PSK) for sessions-
273      * identified by a PSK.
274      *
275      * DTLS mode "PSK with AES 128 CCM 8" for Application CoAPS.
276      *
277      * @param[in]  aPsk          A pointer to the PSK.
278      * @param[in]  aPskLength    The PSK char length.
279      * @param[in]  aPskIdentity  The Identity Name for the PSK.
280      * @param[in]  aPskIdLength  The PSK Identity Length.
281      *
282      * @retval kErrorNone  Successfully set the PSK.
283      *
284      */
285     void SetPreSharedKey(const uint8_t *aPsk, uint16_t aPskLength, const uint8_t *aPskIdentity, uint16_t aPskIdLength);
286 
287 #endif
288 
289 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
290     /**
291      * Sets a reference to the own x509 certificate with corresponding private key.
292      *
293      * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
294      *
295      * @param[in]  aX509Certificate   A pointer to the PEM formatted X509 certificate.
296      * @param[in]  aX509CertLength    The length of certificate.
297      * @param[in]  aPrivateKey        A pointer to the PEM formatted private key.
298      * @param[in]  aPrivateKeyLength  The length of the private key.
299      *
300      */
301     void SetCertificate(const uint8_t *aX509Certificate,
302                         uint32_t       aX509CertLength,
303                         const uint8_t *aPrivateKey,
304                         uint32_t       aPrivateKeyLength);
305 
306     /**
307      * Sets the trusted top level CAs. It is needed for validate the
308      * certificate of the peer.
309      *
310      * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
311      *
312      * @param[in]  aX509CaCertificateChain  A pointer to the PEM formatted X509 CA chain.
313      * @param[in]  aX509CaCertChainLength   The length of chain.
314      *
315      */
316     void SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength);
317 #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
318 
319 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
320     /**
321      * Returns the peer x509 certificate base64 encoded.
322      *
323      * DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
324      *
325      * @param[out]  aPeerCert        A pointer to the base64 encoded certificate buffer.
326      * @param[out]  aCertLength      The length of the base64 encoded peer certificate.
327      * @param[in]   aCertBufferSize  The buffer size of aPeerCert.
328      *
329      * @retval kErrorInvalidState   Not connected yet.
330      * @retval kErrorNone           Successfully get the peer certificate.
331      * @retval kErrorNoBufs         Can't allocate memory for certificate.
332      *
333      */
334     Error GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize);
335 #endif // defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
336 
337 #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
338     /**
339      * Returns an attribute value identified by its OID from the subject
340      * of the peer x509 certificate. The peer OID is provided in binary format.
341      * The attribute length is set if the attribute was successfully read or zero
342      * if unsuccessful. The ASN.1 type as is set as defineded in the ITU-T X.690 standard
343      * if the attribute was successfully read.
344      *
345      * @param[in]     aOid                A pointer to the OID to be found.
346      * @param[in]     aOidLength          The length of the OID.
347      * @param[out]    aAttributeBuffer    A pointer to the attribute buffer.
348      * @param[in,out] aAttributeLength    On input, the size the max size of @p aAttributeBuffer.
349      *                                    On output, the length of the attribute written to the buffer.
350      * @param[out]    aAsn1Type           A pointer to the ASN.1 type of the attribute written to the buffer.
351      *
352      * @retval kErrorInvalidState   Not connected yet.
353      * @retval kErrorInvalidArgs    Invalid attribute length.
354      * @retval kErrorNone           Successfully read attribute.
355      * @retval kErrorNoBufs         Insufficient memory for storing the attribute value.
356      *
357      */
358     Error GetPeerSubjectAttributeByOid(const char *aOid,
359                                        size_t      aOidLength,
360                                        uint8_t    *aAttributeBuffer,
361                                        size_t     *aAttributeLength,
362                                        int        *aAsn1Type);
363 
364     /**
365      * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of
366      * the peer x509 certificate, where the last digit x is set to aThreadOidDescriptor.
367      * The attribute length is set if the attribute was successfully read or zero if unsuccessful.
368      * Requires a connection to be active.
369      *
370      * @param[in]      aThreadOidDescriptor  The last digit of the Thread attribute OID.
371      * @param[out]     aAttributeBuffer      A pointer to the attribute buffer.
372      * @param[in,out]  aAttributeLength      On input, the size the max size of @p aAttributeBuffer.
373      *                                           On output, the length of the attribute written to the buffer.
374      *
375      * @retval kErrorNone             Successfully read attribute.
376      * @retval kErrorInvalidArgs      Invalid attribute length.
377      * @retval kErrorNotFound         The requested attribute was not found.
378      * @retval kErrorNoBufs           Insufficient memory for storing the attribute value.
379      * @retval kErrorInvalidState     Not connected yet.
380      * @retval kErrorNotImplemented   The value of aThreadOidDescriptor is >127.
381      * @retval kErrorParse            The certificate extensions could not be parsed.
382      *
383      */
384     Error GetThreadAttributeFromPeerCertificate(int      aThreadOidDescriptor,
385                                                 uint8_t *aAttributeBuffer,
386                                                 size_t  *aAttributeLength);
387 #endif // defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
388 
389     /**
390      * Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of
391      * the own x509 certificate, where the last digit x is set to aThreadOidDescriptor.
392      * The attribute length is set if the attribute was successfully read or zero if unsuccessful.
393      * Requires a connection to be active.
394      *
395      * @param[in]      aThreadOidDescriptor  The last digit of the Thread attribute OID.
396      * @param[out]     aAttributeBuffer      A pointer to the attribute buffer.
397      * @param[in,out]  aAttributeLength      On input, the size the max size of @p aAttributeBuffer.
398      *                                       On output, the length of the attribute written to the buffer.
399      *
400      * @retval kErrorNone             Successfully read attribute.
401      * @retval kErrorInvalidArgs      Invalid attribute length.
402      * @retval kErrorNotFound         The requested attribute was not found.
403      * @retval kErrorNoBufs           Insufficient memory for storing the attribute value.
404      * @retval kErrorInvalidState     Not connected yet.
405      * @retval kErrorNotImplemented   The value of aThreadOidDescriptor is >127.
406      * @retval kErrorParse            The certificate extensions could not be parsed.
407      *
408      */
409     Error GetThreadAttributeFromOwnCertificate(int      aThreadOidDescriptor,
410                                                uint8_t *aAttributeBuffer,
411                                                size_t  *aAttributeLength);
412 
413     /**
414      * Set the authentication mode for a connection.
415      *
416      * Disable or enable the verification of peer certificate.
417      * Must called before start.
418      *
419      * @param[in]  aVerifyPeerCertificate  true, if the peer certificate should verify.
420      *
421      */
SetSslAuthMode(bool aVerifyPeerCertificate)422     void SetSslAuthMode(bool aVerifyPeerCertificate) { mVerifyPeerCertificate = aVerifyPeerCertificate; }
423 #endif // OPENTHREAD_CONFIG_TLS_API_ENABLE
424 
425 #ifdef MBEDTLS_SSL_SRV_C
426     /**
427      * Sets the Client ID used for generating the Hello Cookie.
428      *
429      * @param[in]  aClientId  A pointer to the Client ID.
430      * @param[in]  aLength    Number of bytes in the Client ID.
431      *
432      * @retval kErrorNone  Successfully set the Client ID.
433      *
434      */
435     Error SetClientId(const uint8_t *aClientId, uint8_t aLength);
436 #endif
437 
438     /**
439      * Sends data within the session.
440      *
441      * @param[in]  aMessage  A message to send via connection.
442      * @param[in]  aLength   Number of bytes in the data buffer.
443      *
444      * @retval kErrorNone     Successfully sent the data via the session.
445      * @retval kErrorNoBufs   A message is too long.
446      *
447      */
448     Error Send(Message &aMessage, uint16_t aLength);
449 
450     /**
451      * Provides a received message to the SecureTransport object.
452      *
453      * @param[in]  aMessage  A reference to the message.
454      *
455      */
456     void Receive(Message &aMessage);
457 
458     /**
459      * Sets the default message sub-type that will be used for all messages without defined
460      * sub-type.
461      *
462      * @param[in]  aMessageSubType  The default message sub-type.
463      *
464      */
SetDefaultMessageSubType(Message::SubType aMessageSubType)465     void SetDefaultMessageSubType(Message::SubType aMessageSubType) { mMessageDefaultSubType = aMessageSubType; }
466 
467     /**
468      * Returns the session's peer address.
469      *
470      * @return session's message info.
471      *
472      */
GetMessageInfo(void) const473     const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
474 
475     /**
476      * Checks and handles a received message provided to the SecureTransport object. If checks based on
477      * the message info and current connection state pass, the message is processed.
478      *
479      * @param[in]  aMessage  A reference to the message to receive.
480      * @param[in]  aMessageInfo A reference to the message info associated with @p aMessage.
481      *
482      */
483     void HandleReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
484 
485 private:
486     enum State : uint8_t
487     {
488         kStateClosed,       // UDP socket is closed.
489         kStateOpen,         // UDP socket is open.
490         kStateInitializing, // The service is initializing.
491         kStateConnecting,   // The service is establishing a connection.
492         kStateConnected,    // The service has a connection established.
493         kStateCloseNotify,  // The service is closing a connection.
494     };
495 
496     static constexpr uint32_t kGuardTimeNewConnectionMilli = 2000;
497 
498 #if !OPENTHREAD_CONFIG_TLS_API_ENABLE
499     static constexpr uint16_t kApplicationDataMaxLength = 1152;
500 #else
501     static constexpr uint16_t         kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH;
502 #endif
503 
504     static constexpr size_t kSecureTransportKeyBlockSize     = 40;
505     static constexpr size_t kSecureTransportRandomBufferSize = 32;
506 
IsStateClosed(void) const507     bool IsStateClosed(void) const { return mState == kStateClosed; }
IsStateOpen(void) const508     bool IsStateOpen(void) const { return mState == kStateOpen; }
IsStateInitializing(void) const509     bool IsStateInitializing(void) const { return mState == kStateInitializing; }
IsStateConnecting(void) const510     bool IsStateConnecting(void) const { return mState == kStateConnecting; }
IsStateConnected(void) const511     bool IsStateConnected(void) const { return mState == kStateConnected; }
IsStateCloseNotify(void) const512     bool IsStateCloseNotify(void) const { return mState == kStateCloseNotify; }
IsStateConnectingOrConnected(void) const513     bool IsStateConnectingOrConnected(void) const { return mState == kStateConnecting || mState == kStateConnected; }
514     void SetState(State aState);
515 
516     void  FreeMbedtls(void);
517     Error Setup(bool aClient);
518 
519 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
520     /**
521      * Set keys and/or certificates for dtls session dependent of used cipher suite.
522      *
523      * @retval mbedtls error, 0 if successfully.
524      *
525      */
526     int SetApplicationSecureKeys(void);
527 
528     Error GetThreadAttributeFromCertificate(const mbedtls_x509_crt *aCert,
529                                             int                     aThreadOidDescriptor,
530                                             uint8_t                *aAttributeBuffer,
531                                             size_t                 *aAttributeLength);
532 #endif
533 
534     static void HandleMbedtlsDebug(void *aContext, int aLevel, const char *aFile, int aLine, const char *aStr);
535     void        HandleMbedtlsDebug(int aLevel, const char *aFile, int aLine, const char *aStr);
536 
537     static int HandleMbedtlsGetTimer(void *aContext);
538     int        HandleMbedtlsGetTimer(void);
539 
540     static void HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish);
541     void        HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish);
542 
543     static int HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength);
544     int        HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength);
545 
546     static int HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength);
547     int        HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength);
548 
549 #ifdef MBEDTLS_SSL_EXPORT_KEYS
550 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
551 
552     static void HandleMbedtlsExportKeys(void                       *aContext,
553                                         mbedtls_ssl_key_export_type aType,
554                                         const unsigned char        *aMasterSecret,
555                                         size_t                      aMasterSecretLen,
556                                         const unsigned char         aClientRandom[32],
557                                         const unsigned char         aServerRandom[32],
558                                         mbedtls_tls_prf_types       aTlsPrfType);
559 
560     void HandleMbedtlsExportKeys(mbedtls_ssl_key_export_type aType,
561                                  const unsigned char        *aMasterSecret,
562                                  size_t                      aMasterSecretLen,
563                                  const unsigned char         aClientRandom[32],
564                                  const unsigned char         aServerRandom[32],
565                                  mbedtls_tls_prf_types       aTlsPrfType);
566 
567 #else
568 
569     static int       HandleMbedtlsExportKeys(void                *aContext,
570                                              const unsigned char *aMasterSecret,
571                                              const unsigned char *aKeyBlock,
572                                              size_t               aMacLength,
573                                              size_t               aKeyLength,
574                                              size_t               aIvLength);
575     int              HandleMbedtlsExportKeys(const unsigned char *aMasterSecret,
576                                              const unsigned char *aKeyBlock,
577                                              size_t               aMacLength,
578                                              size_t               aKeyLength,
579                                              size_t               aIvLength);
580 
581 #endif // (MBEDTLS_VERSION_NUMBER >= 0x03000000)
582 #endif // MBEDTLS_SSL_EXPORT_KEYS
583 
584     static void HandleTimer(Timer &aTimer);
585     void        HandleTimer(void);
586 
587     static void HandleReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
588 
589     void  HandleReceive(const uint8_t *aBuf, uint16_t aLength);
590     Error HandleSecureTransportSend(const uint8_t *aBuf, uint16_t aLength, Message::SubType aMessageSubType);
591 
592     void Process(void);
593 
594 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
595     static const char *StateToString(State aState);
596 #endif
597 
598     State mState;
599 
600     int     mCipherSuites[2];
601     uint8_t mPsk[kPskMaxLength];
602     uint8_t mPskLength;
603 
604 #if (MBEDTLS_VERSION_NUMBER >= 0x03010000)
605     static const uint16_t sGroups[];
606 #else
607     static const mbedtls_ecp_group_id sCurves[];
608 #endif
609 
610 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) || defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
611 #if (MBEDTLS_VERSION_NUMBER >= 0x03020000)
612     static const uint16_t sSignatures[];
613 #else
614     static const int sHashes[];
615 #endif
616 #endif
617 
618 #if OPENTHREAD_CONFIG_TLS_API_ENABLE
619 #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
620     const uint8_t     *mCaChainSrc;
621     uint32_t           mCaChainLength;
622     const uint8_t     *mOwnCertSrc;
623     uint32_t           mOwnCertLength;
624     const uint8_t     *mPrivateKeySrc;
625     uint32_t           mPrivateKeyLength;
626     mbedtls_x509_crt   mCaChain;
627     mbedtls_x509_crt   mOwnCert;
628     mbedtls_pk_context mPrivateKey;
629 #endif
630 #ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
631     const uint8_t *mPreSharedKey;
632     const uint8_t *mPreSharedKeyIdentity;
633     uint16_t       mPreSharedKeyLength;
634     uint16_t       mPreSharedKeyIdLength;
635 #endif
636 #endif
637 
638     bool mVerifyPeerCertificate;
639 
640     mbedtls_ssl_context mSsl;
641     mbedtls_ssl_config  mConf;
642 
643 #ifdef MBEDTLS_SSL_COOKIE_C
644     mbedtls_ssl_cookie_ctx mCookieCtx;
645 #endif
646 
647     TimerMilliContext mTimer;
648 
649     TimeMilli mTimerIntermediate;
650     bool      mTimerSet : 1;
651 
652     bool mLayerTwoSecurity : 1;
653     bool mDatagramTransport : 1;
654 
655     uint16_t                    mMaxConnectionAttempts;
656     uint16_t                    mRemainingConnectionAttempts;
657     Callback<AutoCloseCallback> mAutoCloseCallback;
658 
659     Message *mReceiveMessage;
660 
661     Callback<ConnectedHandler> mConnectedCallback;
662     Callback<ReceiveHandler>   mReceiveCallback;
663     void                      *mContext;
664 
665     Ip6::MessageInfo mMessageInfo;
666     Ip6::Udp::Socket mSocket;
667 
668     Callback<TransportCallback> mTransportCallback;
669     void                       *mTransportContext;
670 
671     Message::SubType mMessageSubType;
672     Message::SubType mMessageDefaultSubType;
673 };
674 
675 } // namespace MeshCoP
676 } // namespace ot
677 
678 #endif // SECURE_TRANSPORT_HPP_
679