mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 21:27:46 +00:00
[coaps] CoAP Secure Client/Server accessible through OT API (#2716)
This commit is contained in:
committed by
Jonathan Hui
parent
5fe9038e33
commit
2ce47a8e9c
@@ -52,6 +52,7 @@ set -x
|
||||
--with-ncp-bus=uart \
|
||||
--with-examples=posix \
|
||||
--enable-application-coap \
|
||||
--enable-application-coap-secure \
|
||||
--enable-border-router \
|
||||
--enable-cert-log \
|
||||
--enable-child-supervision \
|
||||
|
||||
+33
-1
@@ -764,6 +764,37 @@ AC_SUBST(OPENTHREAD_ENABLE_MTD_NETWORK_DIAGNOSTIC)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_MTD_NETWORK_DIAGNOSTIC], [test "${enable_mtd_network_diagnostic}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_MTD_NETWORK_DIAGNOSTIC],[${OPENTHREAD_ENABLE_MTD_NETWORK_DIAGNOSTIC}],[Define to 1 to enable network diagnostic for MTD.])
|
||||
|
||||
#
|
||||
# Application CoAP Secure
|
||||
#
|
||||
|
||||
AC_ARG_ENABLE(application_coap_secure,
|
||||
[AS_HELP_STRING([--enable-application-coap-secure],[Enable CoAP Secure to an application.@<:@default=no@:>@.])],
|
||||
[
|
||||
case "${enableval}" in
|
||||
|
||||
no|yes)
|
||||
enable_application_coap_secure=${enableval}
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid value ${enable_application_coap_secure} for --enable-application-coap_secure])
|
||||
;;
|
||||
esac
|
||||
],
|
||||
[enable_application_coap_secure=no])
|
||||
|
||||
if test "$enable_application_coap_secure" = "yes"; then
|
||||
OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE=1
|
||||
enable_application_coap="yes"
|
||||
else
|
||||
OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE=0
|
||||
fi
|
||||
|
||||
AC_SUBST(OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE], [test "${enable_application_coap_secure}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE],[${OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE}],[Define to 1 if you want to enable CoAP Secure to an application.])
|
||||
|
||||
#
|
||||
# Thread Commissioner
|
||||
#
|
||||
@@ -828,7 +859,7 @@ AC_SUBST(OPENTHREAD_ENABLE_JOINER)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_JOINER], [test "${enable_joiner}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_JOINER],[${OPENTHREAD_ENABLE_JOINER}],[Define to 1 to enable the joiner role.])
|
||||
|
||||
if test "${enable_commissioner}" = "yes" -o "${enable_joiner}" = "yes" -o "${enable_border_agent}" = "yes"; then
|
||||
if test "${enable_commissioner}" = "yes" -o "${enable_joiner}" = "yes" -o "${enable_border_agent}" = "yes" -o "${enable_application_coap_secure}" = "yes"; then
|
||||
enable_dtls="yes"
|
||||
OPENTHREAD_ENABLE_DTLS=1
|
||||
else
|
||||
@@ -1787,6 +1818,7 @@ AC_MSG_NOTICE([
|
||||
OpenThread DHCPv6 Client support : ${enable_dhcp6_client}
|
||||
OpenThread DNS Client support : ${enable_dns_client}
|
||||
OpenThread Application CoAP support : ${enable_application_coap}
|
||||
OpenThread Application CoAP Secure support: ${enable_application_coap_secure}
|
||||
OpenThread Raw Link-Layer support : ${enable_raw_link_api}
|
||||
OpenThread Border Agent support : ${enable_border_agent}
|
||||
OpenThread Border Router support : ${enable_border_router}
|
||||
|
||||
@@ -43,6 +43,10 @@ ifeq ($(COAP),1)
|
||||
configure_OPTIONS += --enable-application-coap
|
||||
endif
|
||||
|
||||
ifeq ($(COAPS),1)
|
||||
configure_OPTIONS += --enable-application-coap-secure
|
||||
endif
|
||||
|
||||
ifeq ($(COMMISSIONER),1)
|
||||
configure_OPTIONS += --enable-commissioner
|
||||
endif
|
||||
|
||||
@@ -51,6 +51,7 @@ openthread_headers = \
|
||||
channel_monitor.h \
|
||||
child_supervision.h \
|
||||
cli.h \
|
||||
coap_secure.h \
|
||||
coap.h \
|
||||
commissioner.h \
|
||||
config.h \
|
||||
|
||||
@@ -160,6 +160,9 @@ typedef enum otCoapOptionContentFormat {
|
||||
OT_COAP_OPTION_CONTENT_FORMAT_OCTET_STREAM = 42, ///< application/octet-stream
|
||||
OT_COAP_OPTION_CONTENT_FORMAT_EXI = 47, ///< application/exi
|
||||
OT_COAP_OPTION_CONTENT_FORMAT_JSON = 50, ///< application/json
|
||||
OT_COAP_OPTION_CONTENT_FORMAT_PKCS10 = 70, ///< application/pkcs10
|
||||
OT_COAP_OPTION_CONTENT_FORMAT_PKCS7 = 80, ///< application/pkcs7
|
||||
OT_COAP_OPTION_CONTENT_FORMAT_JWS = 101 ///< application/json-web-signature
|
||||
} otCoapOptionContentFormat;
|
||||
|
||||
#define OT_COAP_HEADER_MAX_LENGTH 128 ///< Max CoAP header length (bytes)
|
||||
@@ -402,6 +405,16 @@ otCoapType otCoapHeaderGetType(const otCoapHeader *aHeader);
|
||||
*/
|
||||
otCoapCode otCoapHeaderGetCode(const otCoapHeader *aHeader);
|
||||
|
||||
/**
|
||||
* This method returns the CoAP Code as human readable string.
|
||||
*
|
||||
* @param[in] aHeader A pointer to the CoAP header.
|
||||
*
|
||||
* @ returns The CoAP Code as string.
|
||||
*
|
||||
*/
|
||||
const char *otCoapHeaderCodeToString(const otCoapHeader *aHeader);
|
||||
|
||||
/**
|
||||
* This function returns the Message ID value.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file defines the top-level functions for the OpenThread CoAP Secure implementation.
|
||||
*
|
||||
* @note
|
||||
* To enable cipher suite DTLS_PSK_WITH_AES_128_CCM_8, MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
* must be enabled in mbedtls-config.h
|
||||
* To enable cipher suite DTLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
|
||||
* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED must be enabled in mbedtls-config.h.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_COAP_SECURE_H_
|
||||
#define OPENTHREAD_COAP_SECURE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread/coap.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup api-coap-secure
|
||||
*
|
||||
* @brief
|
||||
* This module includes functions that control CoAP Secure (CoAP over DTLS) communication.
|
||||
*
|
||||
* The functions in this module are available when application-coap-secure feature
|
||||
* (`OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE`) is enabled.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
#define OT_DEFAULT_COAP_SECURE_PORT 5684 ///< Default CoAP Secure port, as specified in RFC 7252
|
||||
|
||||
/**
|
||||
* This function pointer is called when the DTLS connection state changes.
|
||||
*
|
||||
* @param[in] aConnected true, if a connection was established, false otherwise.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
typedef void (*otHandleCoapSecureClientConnect)(bool aConnected, void *aContext);
|
||||
|
||||
/**
|
||||
* This function starts the CoAP Secure service.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aPort The local UDP port to bind to.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the CoAP Secure server.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort, void *aContext);
|
||||
|
||||
/**
|
||||
* This function stops the CoAP Secure server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully stopped the CoAP Secure server.
|
||||
*/
|
||||
otError otCoapSecureStop(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method sets the Pre-Shared Key (PSK) and cipher suite
|
||||
* DTLS_PSK_WITH_AES_128_CCM_8.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aPSK A pointer to the PSK.
|
||||
* @param[in] aPskLength The PSK length.
|
||||
* @param[in] aPskIdentity The Identity Name for the PSK.
|
||||
* @param[in] aPskIdLength The PSK Identity Length.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the PSK.
|
||||
* @retval OT_ERROR_INVALID_ARGS The PSK is invalid.
|
||||
* @retval OT_ERROR_DISABLED_FEATURE Mbedtls config not enabled
|
||||
* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureSetPsk(otInstance * aInstance,
|
||||
const uint8_t *aPsk,
|
||||
uint16_t aPskLength,
|
||||
const uint8_t *aPskIdentity,
|
||||
uint16_t aPskIdLength);
|
||||
|
||||
/**
|
||||
* This method returns the peer x509 certificate base64 encoded.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[out] aPeerCert A pointer to the base64 encoded certificate buffer.
|
||||
* @param[out] aCertLength The length of the base64 encoded peer certificate.
|
||||
* @param[in] aCertBufferSize The buffer size of aPeerCert.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully get the peer certificate.
|
||||
* @retval OT_ERROR_DISABLED_FEATURE Mbedtls config not enabled MBEDTLS_BASE64_C.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureGetPeerCertificateBase64(otInstance * aInstance,
|
||||
unsigned char *aPeerCert,
|
||||
uint64_t * aCertLength,
|
||||
uint64_t aCertBufferSize);
|
||||
|
||||
/**
|
||||
* This method sets the authentication mode for the coap secure connection.
|
||||
*
|
||||
* Disable or enable the verification of peer certificate.
|
||||
* Must be called before start.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aVerifyPeerCertificate true, to verify the peer certificate.
|
||||
*
|
||||
*/
|
||||
void otCoapSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate);
|
||||
|
||||
/**
|
||||
* This method sets the local device's X509 certificate with corresponding private key for
|
||||
* DTLS session with DTLS_ECDHE_ECDSA_WITH_AES_128_CCM_8.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aX509Certificate A pointer to the PEM formatted X509 certificate.
|
||||
* @param[in] aX509Length The length of certificate.
|
||||
* @param[in] aPrivateKey A pointer to the PEM formatted private key.
|
||||
* @param[in] aPrivateKeyLength The length of the private key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the x509 certificate
|
||||
* with his private key.
|
||||
* @retval OT_ERROR_DISABLED_FEATURE Mbedtls config not enabled
|
||||
* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureSetCertificate(otInstance * aInstance,
|
||||
const uint8_t *aX509Cert,
|
||||
uint32_t aX509Length,
|
||||
const uint8_t *aPrivateKey,
|
||||
uint32_t aPrivateKeyLength);
|
||||
|
||||
/**
|
||||
* This method sets the trusted top level CAs. It is needed for validating the
|
||||
* certificate of the peer.
|
||||
*
|
||||
* DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain.
|
||||
* @param[in] aX509CaCertChainLength The length of chain.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the the trusted top level CAs.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureSetCaCertificateChain(otInstance * aInstance,
|
||||
const uint8_t *aX509CaCertificateChain,
|
||||
uint32_t aX509CaCertChainLength);
|
||||
|
||||
/**
|
||||
* This method initializes DTLS session with a peer.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMessageInfo A pointer to a message info structure.
|
||||
* @param[in] aCallback A pointer to a function that will be called when the DTLS connection
|
||||
* state changes.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started DTLS connection.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureConnect(otInstance * aInstance,
|
||||
const otMessageInfo * aMessageInfo,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This method stops the DTLS connection.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully stopped the DTLS connection.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureDisconnect(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the DTLS session is connected.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval TRUE The DTLS session is connected.
|
||||
* @retval FALSE The DTLS session is not connected.
|
||||
*
|
||||
*/
|
||||
bool otCoapSecureIsConnected(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the DTLS session is active.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval TRUE If DTLS session is active.
|
||||
* @retval FALSE If DTLS session is not active.
|
||||
*
|
||||
*/
|
||||
bool otCoapSecureIsConncetionActive(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method sends a CoAP request over secure DTLS connection.
|
||||
*
|
||||
* If a response for a request is expected, respective function and context information should be provided.
|
||||
* If no response is expected, these arguments should be NULL pointers.
|
||||
* If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aHandler A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully sent CoAP message.
|
||||
* @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data.
|
||||
* @retvak OT_ERROR_INVALID_STATE DTLS connection was not initialized.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureSendRequest(otInstance * aInstance,
|
||||
otMessage * aMessage,
|
||||
otCoapResponseHandler aHandler,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function adds a resource to the CoAP Secure server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aResource A pointer to the resource.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully added @p aResource.
|
||||
* @retval OT_ERROR_ALREADY The @p aResource was already added.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource);
|
||||
|
||||
/**
|
||||
* This function removes a resource from the CoAP Secure server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aResource A pointer to the resource.
|
||||
*
|
||||
*/
|
||||
void otCoapSecureRemoveResource(otInstance *aInstance, otCoapResource *aResource);
|
||||
|
||||
/**
|
||||
* This function sets the default handler for unhandled CoAP Secure requests.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aHandler A function pointer that shall be called when an unhandled request arrives.
|
||||
* @param[in] aContext A pointer to arbitrary context information. May be NULL if not used.
|
||||
*
|
||||
*/
|
||||
void otCoapSecureSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* This method sets the connected callback to indicate, when
|
||||
* a Client connect to the CoAP Secure server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMessageInfo A pointer to a message info structure.
|
||||
* @param[in] aHandler A pointer to a function that will be called once DTLS connection is established.
|
||||
*
|
||||
*/
|
||||
void otCoapSecureSetClientConnectedCallback(otInstance * aInstance,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This function sends a CoAP response from the CoAP Secure server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMessage A pointer to the CoAP response to send.
|
||||
* @param[in] aMessageInfo A pointer to the message info associated with @p aMessage.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully enqueued the CoAP response message.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient buffers available to send the CoAP response.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* OPENTHREAD_COAP_SECURE_H_ */
|
||||
@@ -144,6 +144,7 @@ libopenthread_cli_ftd_a_CPPFLAGS = \
|
||||
SOURCES_COMMON = \
|
||||
cli.cpp \
|
||||
cli_coap.cpp \
|
||||
cli_coap_secure.cpp \
|
||||
cli_console.cpp \
|
||||
cli_dataset.cpp \
|
||||
cli_uart.cpp \
|
||||
@@ -161,6 +162,7 @@ libopenthread_cli_mtd_a_SOURCES = \
|
||||
noinst_HEADERS = \
|
||||
cli.hpp \
|
||||
cli_coap.hpp \
|
||||
cli_coap_secure.hpp \
|
||||
cli_console.hpp \
|
||||
cli_dataset.hpp \
|
||||
cli_server.hpp \
|
||||
|
||||
+100
-1
@@ -14,6 +14,7 @@ OpenThread test scripts use the CLI to execute test cases.
|
||||
* [childmax](#childmax)
|
||||
* [childtimeout](#childtimeout)
|
||||
* [coap](#coap-start)
|
||||
* [coaps](#coaps-start-checkpeercert)
|
||||
* [commissioner](#commissioner-start-provisioningurl)
|
||||
* [contextreusedelay](#contextreusedelay)
|
||||
* [counter](#counter)
|
||||
@@ -233,7 +234,7 @@ Coap service started: Done
|
||||
Stops the application coap service.
|
||||
|
||||
```bash
|
||||
> coap start
|
||||
> coap stop
|
||||
Coap service stopped: Done
|
||||
```
|
||||
|
||||
@@ -272,6 +273,104 @@ coap response sent successfully!
|
||||
Received coap response
|
||||
```
|
||||
|
||||
### coaps start \<checkPeerCert\>
|
||||
|
||||
Starts the Application CoAP Secure Service.
|
||||
|
||||
* checkPeerCert: Peer Certificate Check can be disabled by typing false.
|
||||
|
||||
```bash
|
||||
> coaps start false
|
||||
Verify Peer Certificate: false. Coap Secure service started: Done
|
||||
> coaps start
|
||||
Verify Peer Certificate: true. Coap Secure service started: Done
|
||||
```
|
||||
|
||||
### coaps stop
|
||||
|
||||
Stops the Application CoAP Secure Service.
|
||||
|
||||
```bash
|
||||
> coaps stop
|
||||
Coap Secure service stopped: Done
|
||||
```
|
||||
|
||||
### coaps set psk \<preSharedKey\> \<keyIdentity\>
|
||||
|
||||
Set a pre-shared key with his identifier and the ciphersuite
|
||||
"DTLS_PSK_WITH_AES_128_CCM_8" for the dtls session.
|
||||
|
||||
* preSharedKey: The pre-shared key (PSK) for dtls session.
|
||||
* keyIdentity: The identifier for the PSK.
|
||||
|
||||
```bash
|
||||
> coaps set psk myPreSharedSecret myIdentifier
|
||||
Coap Secure set PSK: Done
|
||||
```
|
||||
|
||||
### coaps set x509
|
||||
|
||||
Set X.509 Certificate with his private key, which is saved in
|
||||
src/cli/x509_cert_key.hpp.
|
||||
|
||||
```bash
|
||||
> coaps set x509
|
||||
Coap Secure set own .X509 certificate: Done
|
||||
```
|
||||
|
||||
### coaps connect \<serverAddress\> \[port\]
|
||||
|
||||
Open a dtls session to a CoAP Secure Server.
|
||||
|
||||
* serverAddress: IPv6 address of Server
|
||||
|
||||
```bash
|
||||
> coaps connect 2001:1234::321
|
||||
Coap Secure connect: Done
|
||||
CoAP Secure connected!
|
||||
```
|
||||
|
||||
### coaps disconnect
|
||||
|
||||
Terminate the dtls session to the Server.
|
||||
|
||||
```bash
|
||||
> coaps disconnect
|
||||
CoAP Secure not connected or disconnected.
|
||||
Done
|
||||
```
|
||||
|
||||
### coaps \<method\> \<address\> \<uri\> \[type\] \[payload\]
|
||||
|
||||
* method: CoAP method to be used (GET/PUT/POST/DELETE).
|
||||
* address: IPv6 address of the CoAP Secure server to query.
|
||||
* uri: URI String of the resource on the CoAP server.
|
||||
* type: Switch between confirmable ("con") and non-confirmable (default).
|
||||
* payload: In case of PUT/POST/DELETE a payload can be encapsulated.
|
||||
|
||||
```bash
|
||||
> coaps get 2001:1234::321 secret
|
||||
Sending coap secure request: Done
|
||||
Received coap secure response
|
||||
CoapSecure RX Header Informations:
|
||||
Type 16 (NON CONF)
|
||||
Code 69 (Coap Code CONTENT)
|
||||
With payload (hex):
|
||||
4a756e2031322031353a30373a3336
|
||||
> coaps put 2001:1234::321 test non-con hello
|
||||
Sending coap secure request: Done
|
||||
> coaps post 2001:1234::321 test con
|
||||
Sending coap secure request: Done
|
||||
Received coap secure response
|
||||
CoapSecure RX Header Informations:
|
||||
Type 32 (NON CONF)
|
||||
Code 69 (Coap Code CONTENT)
|
||||
With payload (hex):
|
||||
4a756e2031322031353a30373a3336
|
||||
> coaps delete 2001:1234::321 test
|
||||
Sending coap secure request: Done
|
||||
```
|
||||
|
||||
### commissioner start \<provisioningUrl\>
|
||||
|
||||
Start the Commissioner role.
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
# OpenThread CLI - COAPS Example
|
||||
|
||||
The OpenThread CoAP Secure APIs may be invoked via the OpenThread CLI.
|
||||
|
||||
CoAP Secure use DTLS (over UDP) to make an end to end encrypted connection.
|
||||
|
||||
### For use PSK with AES128 CCM8
|
||||
|
||||
1a. enter your psk and his identifier
|
||||
|
||||
```bash
|
||||
coaps set psk <yourPsk> <PskIdentifier>
|
||||
```
|
||||
|
||||
### For use ECDHE ECDSA with AES128 CCM8
|
||||
|
||||
1b. set the private key and .X509 certificate stored in core/cli/x509_cert_key.hpp.
|
||||
|
||||
> _optional_: add your [own](#create-ec-private-key) X.509 certificate and private key to 'core/cli/x509_cert_key.hpp'.
|
||||
|
||||
```bash
|
||||
coaps set x509
|
||||
```
|
||||
|
||||
## Start CoAPS Service (for Server and Client)
|
||||
|
||||
2. start (init) the coaps api and starts listen on coaps port (5684)
|
||||
|
||||
```bash
|
||||
> coaps start
|
||||
```
|
||||
|
||||
## CoAP Secure Server
|
||||
|
||||
* add a coap resource to provide to a coap client
|
||||
|
||||
```bash
|
||||
coaps resource <coapUri>
|
||||
```
|
||||
|
||||
## Connect to a DTLS Server
|
||||
|
||||
* connect to a dtls server
|
||||
|
||||
```bash
|
||||
coaps connect <serversIp> (port, if not default)
|
||||
```
|
||||
|
||||
## CoAP Secure Client
|
||||
|
||||
* get a resource form the server
|
||||
|
||||
```bash
|
||||
coaps get (serversIp) <coapUri> (Con/NotCon) (payload)
|
||||
```
|
||||
|
||||
> post, put and delete also possible
|
||||
|
||||
|
||||
<> must
|
||||
() opt
|
||||
|
||||
|
||||
## Complete example for DTLS/CoAP server (Node 1)
|
||||
|
||||
In this example the coap server is also the dtls server.
|
||||
The dtls server waits for incoming connection on coaps port 5684.
|
||||
The [Node 2](#complete-example-dtlscoap-client-node-2) below is able to connect to this coaps server.
|
||||
|
||||
> Note: Node 1 and Node 2 must use the same mode. Either PSK or Certificate based.
|
||||
|
||||
```
|
||||
Node 1
|
||||
---------
|
||||
|CoAPS |
|
||||
|Server | <--Listen on Port 5684-- (Node 2)
|
||||
| |
|
||||
---------
|
||||
```
|
||||
|
||||
### with PSK
|
||||
|
||||
```bash
|
||||
coaps set psk secretPSK Client_identity
|
||||
coaps start
|
||||
coaps resource test
|
||||
```
|
||||
|
||||
### with Certificate
|
||||
|
||||
```bash
|
||||
coaps set x509
|
||||
coaps start (false)
|
||||
coaps resource test
|
||||
```
|
||||
|
||||
* param false: optional, disables peer certificate validation.
|
||||
|
||||
## Complete example DTLS/CoAP client (Node 2)
|
||||
|
||||
In this example the coap client is also the dtls client.
|
||||
The dlts client can connect to a coaps server which is listen on coaps port 5684, e.g to the [Node 1](#complete-example-for-dtlscoap-server-node-1) above.
|
||||
|
||||
> Note: Node 1 and Node 2 must use the same mode. Either PSK or Certificate based.
|
||||
|
||||
```
|
||||
Node 2
|
||||
---------
|
||||
|CoAPS |
|
||||
|Client |--Connect to Server on Port 5684--> (Node 1)
|
||||
| |
|
||||
---------
|
||||
```
|
||||
|
||||
### with PSK
|
||||
|
||||
```bash
|
||||
coaps set psk secretPSK Client_identity
|
||||
coaps start
|
||||
coaps connect 2001:620:190:ffa1::321
|
||||
coaps get test
|
||||
coaps disconnect
|
||||
```
|
||||
|
||||
### with Certificate
|
||||
|
||||
```bash
|
||||
coaps set x509
|
||||
coaps start (false)
|
||||
coaps connect <server_ip>
|
||||
coaps get test
|
||||
coaps disconnect
|
||||
```
|
||||
|
||||
* param false: optional, disables peer certificate validation.
|
||||
|
||||
## Create own Private Key with a .X509 Certificate
|
||||
|
||||
### Create EC Private Key
|
||||
|
||||
```bash
|
||||
openssl ecparam -genkey -out myECKey.pem -name prime256v1 -noout
|
||||
```
|
||||
|
||||
* ecparam: Key for Elliptic Curve Algorithms
|
||||
* -name: The elliptic curve to chose. a list of available curves `openssl ecparam -list_curves`
|
||||
* -noout: private key without EC Parameters
|
||||
|
||||
### Create .X509 Certificate
|
||||
|
||||
```bash
|
||||
openssl req -x509 -new -key myECKey.pem -out myX509Cert.pem -days 30
|
||||
```
|
||||
|
||||
* -days: validity time of certificate
|
||||
@@ -80,6 +80,10 @@
|
||||
#include "cli_coap.hpp"
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#include "cli_coap_secure.hpp"
|
||||
#endif
|
||||
|
||||
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
|
||||
#include <openthread/platform/debug_uart.h>
|
||||
#endif
|
||||
@@ -106,6 +110,9 @@ const struct Command Interpreter::sCommands[] = {
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
{"coap", &Interpreter::ProcessCoap},
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
{"coaps", &Interpreter::ProcessCoapSecure},
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
{"commissioner", &Interpreter::ProcessCommissioner},
|
||||
#endif
|
||||
@@ -287,6 +294,9 @@ Interpreter::Interpreter(Instance *aInstance)
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
, mCoap(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
, mCoapSecure(*this)
|
||||
#endif
|
||||
{
|
||||
#ifdef OTDLL
|
||||
assert(mApiInstance);
|
||||
@@ -649,6 +659,17 @@ void Interpreter::ProcessCoap(int argc, char *argv[])
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
void Interpreter::ProcessCoapSecure(int argc, char *argv[])
|
||||
{
|
||||
otError error;
|
||||
error = mCoapSecure.Process(argc, argv);
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
void Interpreter::ProcessContextIdReuseDelay(int argc, char *argv[])
|
||||
{
|
||||
|
||||
@@ -50,6 +50,11 @@
|
||||
#include "cli/cli_coap.hpp"
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#include <coap/coap_header.hpp>
|
||||
#include "cli/cli_coap_secure.hpp"
|
||||
#endif
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/instance.hpp"
|
||||
|
||||
@@ -94,6 +99,7 @@ struct Command
|
||||
class Interpreter
|
||||
{
|
||||
friend class Coap;
|
||||
friend class CoapsSecure;
|
||||
friend class UdpExample;
|
||||
|
||||
public:
|
||||
@@ -192,6 +198,9 @@ private:
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
void ProcessCoap(int argc, char *argv[]);
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
void ProcessCoapSecure(int argc, char *argv[]);
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
void ProcessCommissioner(int argc, char *argv[]);
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
@@ -436,6 +445,11 @@ private:
|
||||
Coap mCoap;
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
CoapsSecure mCoapSecure;
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
|
||||
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements a simple CLI for the CoAP Secure service.
|
||||
*/
|
||||
|
||||
#include "cli_coap_secure.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cli/cli.hpp"
|
||||
#include "coap/coap_header.hpp"
|
||||
#include "coap/coap_secure.hpp"
|
||||
|
||||
// header for place your x509 certificate and private key
|
||||
#include "x509_cert_key.hpp"
|
||||
|
||||
#include <mbedtls/debug.h>
|
||||
|
||||
namespace ot {
|
||||
namespace Cli {
|
||||
|
||||
CoapsSecure::CoapsSecure(Interpreter &aInterpreter)
|
||||
: mInterpreter(aInterpreter)
|
||||
, mShutdownFlag(false)
|
||||
, mUseCertificate(false)
|
||||
, mPskLength(0)
|
||||
, mPskIdLength(0)
|
||||
{
|
||||
memset(&mResource, 0, sizeof(mResource));
|
||||
memset(&mPsk, 0, sizeof(mPsk));
|
||||
memset(&mPskId, 0, sizeof(mPskId));
|
||||
}
|
||||
|
||||
void CoapsSecure::PrintHeaderInfos(otCoapHeader *aHeader) const
|
||||
{
|
||||
otCoapCode mCoapCode;
|
||||
otCoapType mCoapType;
|
||||
|
||||
mCoapCode = otCoapHeaderGetCode(aHeader);
|
||||
mCoapType = otCoapHeaderGetType(aHeader);
|
||||
|
||||
mInterpreter.mServer->OutputFormat("\r\n CoapSecure RX Header Information:"
|
||||
"\r\n Type %d => ",
|
||||
static_cast<uint16_t>(mCoapType));
|
||||
|
||||
switch (mCoapType)
|
||||
{
|
||||
case OT_COAP_TYPE_ACKNOWLEDGMENT:
|
||||
mInterpreter.mServer->OutputFormat("Ack");
|
||||
break;
|
||||
case OT_COAP_TYPE_CONFIRMABLE:
|
||||
mInterpreter.mServer->OutputFormat("Confirmable");
|
||||
break;
|
||||
case OT_COAP_TYPE_NON_CONFIRMABLE:
|
||||
mInterpreter.mServer->OutputFormat("NonConfirmable");
|
||||
break;
|
||||
case OT_COAP_TYPE_RESET:
|
||||
mInterpreter.mServer->OutputFormat("Reset");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mInterpreter.mServer->OutputFormat("\r\n Code %d => %s\r\n", static_cast<uint16_t>(mCoapCode),
|
||||
static_cast<const char *>(otCoapHeaderCodeToString(aHeader)));
|
||||
}
|
||||
|
||||
void CoapsSecure::PrintPayload(otMessage *aMessage) const
|
||||
{
|
||||
uint8_t buf[kMaxBufferSize];
|
||||
uint16_t bytesToPrint;
|
||||
uint16_t bytesPrinted = 0;
|
||||
uint16_t length = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat(" With payload [UTF8]:\r\n", aMessage);
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
bytesToPrint = (length < sizeof(buf)) ? length : sizeof(buf);
|
||||
otMessageRead(aMessage, otMessageGetOffset(aMessage) + bytesPrinted, buf, bytesToPrint);
|
||||
|
||||
for (int i = 0; i < bytesToPrint; i++)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("%c", buf[i]);
|
||||
}
|
||||
mInterpreter.mServer->OutputFormat("\r\n");
|
||||
|
||||
length -= bytesToPrint;
|
||||
bytesPrinted += bytesToPrint;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat(" No payload.");
|
||||
}
|
||||
|
||||
mInterpreter.mServer->OutputFormat("\r\n> ");
|
||||
}
|
||||
|
||||
otError CoapsSecure::Process(int argc, char *argv[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otIp6Address coapDestinationIp;
|
||||
otMessageInfo messageInfo;
|
||||
bool mVerifyPeerCert = true;
|
||||
long value;
|
||||
|
||||
VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (strcmp(argv[0], "start") == 0)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
if (strcmp(argv[1], "false") == 0)
|
||||
{
|
||||
mVerifyPeerCert = false;
|
||||
}
|
||||
else if (strcmp(argv[1], "true") != 0)
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
otCoapSecureSetSslAuthMode(mInterpreter.mInstance, mVerifyPeerCert);
|
||||
SuccessOrExit(error = otCoapSecureStart(mInterpreter.mInstance, OT_DEFAULT_COAP_SECURE_PORT, this));
|
||||
otCoapSecureSetClientConnectedCallback(mInterpreter.mInstance, &CoapsSecure::HandleClientConnect, this);
|
||||
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
otCoapSecureSetDefaultHandler(mInterpreter.mInstance, &CoapsSecure::DefaultHandle, this);
|
||||
#endif // CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
if (mUseCertificate)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("Verify Peer Certificate: %s. Coap Secure service started: ",
|
||||
mVerifyPeerCert ? "true" : "false");
|
||||
}
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
}
|
||||
else if (strcmp(argv[0], "set") == 0)
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
if (strcmp(argv[1], "psk") == 0)
|
||||
{
|
||||
if (argc > 3)
|
||||
{
|
||||
mPskLength = (uint8_t)strlen(argv[2]);
|
||||
mPskIdLength = (uint8_t)strlen(argv[3]);
|
||||
|
||||
memcpy(mPsk, argv[2], mPskLength);
|
||||
memcpy(mPskId, argv[3], mPskIdLength);
|
||||
|
||||
SuccessOrExit(
|
||||
error = otCoapSecureSetPsk(mInterpreter.mInstance, mPsk, mPskLength, mPskId, mPskIdLength));
|
||||
mUseCertificate = false;
|
||||
mInterpreter.mServer->OutputFormat("Coap Secure set PSK: ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[1], "x509") == 0)
|
||||
{
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
SuccessOrExit(error = otCoapSecureSetCertificate(
|
||||
mInterpreter.mInstance, (const uint8_t *)OT_CLI_COAPS_X509_CERT,
|
||||
sizeof(OT_CLI_COAPS_X509_CERT), (const uint8_t *)OT_CLI_COAPS_PRIV_KEY,
|
||||
sizeof(OT_CLI_COAPS_PRIV_KEY)));
|
||||
|
||||
SuccessOrExit(error = otCoapSecureSetCaCertificateChain(
|
||||
mInterpreter.mInstance, (const uint8_t *)OT_CLI_COAPS_TRUSTED_ROOT_CERTIFICATE,
|
||||
sizeof(OT_CLI_COAPS_TRUSTED_ROOT_CERTIFICATE)));
|
||||
mUseCertificate = true;
|
||||
|
||||
mInterpreter.mServer->OutputFormat("Coap Secure set own .X509 certificate: ");
|
||||
#else
|
||||
ExitNow(error = OT_ERROR_DISABLED_FEATURE);
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[0], "connect") == 0)
|
||||
{
|
||||
// Destination IPv6 address
|
||||
if (argc > 1)
|
||||
{
|
||||
// parse ipAddr
|
||||
SuccessOrExit(error = otIp6AddressFromString(argv[1], &coapDestinationIp));
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
messageInfo.mPeerAddr = coapDestinationIp;
|
||||
messageInfo.mPeerPort = OT_DEFAULT_COAP_SECURE_PORT;
|
||||
messageInfo.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
|
||||
|
||||
// check for port specification
|
||||
if (argc > 2)
|
||||
{
|
||||
error = Interpreter::ParseLong(argv[2], value);
|
||||
SuccessOrExit(error);
|
||||
messageInfo.mPeerPort = static_cast<uint16_t>(value);
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otCoapSecureConnect(mInterpreter.mInstance, &messageInfo,
|
||||
&CoapsSecure::HandleClientConnect, this));
|
||||
mInterpreter.mServer->OutputFormat("Coap Secure connect: ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[0], "resource") == 0)
|
||||
{
|
||||
mResource.mUriPath = mUriPath;
|
||||
mResource.mContext = this;
|
||||
mResource.mHandler = &CoapsSecure::HandleServerResponse;
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
strlcpy(mUriPath, argv[1], kMaxUriLength);
|
||||
SuccessOrExit(error = otCoapSecureAddResource(mInterpreter.mInstance, &mResource));
|
||||
}
|
||||
|
||||
mInterpreter.mServer->OutputFormat("Resource name is '%s': ", mResource.mUriPath);
|
||||
}
|
||||
else if (strcmp(argv[0], "disconnect") == 0)
|
||||
{
|
||||
SuccessOrExit(error = otCoapSecureDisconnect(mInterpreter.mInstance));
|
||||
}
|
||||
else if (strcmp(argv[0], "stop") == 0)
|
||||
{
|
||||
if (otCoapSecureIsConncetionActive(mInterpreter.mInstance))
|
||||
{
|
||||
error = otCoapSecureDisconnect(mInterpreter.mInstance);
|
||||
mShutdownFlag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = Stop());
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[0], "help") == 0)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("CLI CoAPS help:\r\n\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps start (false)' "
|
||||
": start coap secure service, false disable peer cert verification\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps set psk <psk> <client id>' "
|
||||
": set Preshared Key and Client Identity (Ciphresuit PSK_AES128)\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps set x509' "
|
||||
": set X509 Cert und Private Key (Ciphresuit ECDHE_ECDSA_AES128)\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps connect <servers ipv6 addr> (port)' "
|
||||
": start dtls session with a server\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps get' 'coaps put' 'coaps post' 'coaps delete' "
|
||||
": interact with coap resource from server, ipv6 is not need as client\r\n");
|
||||
mInterpreter.mServer->OutputFormat(
|
||||
" >> args:(ipv6_addr_srv) <coap_src> and, if you have payload: <con> <payload>\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps resource <uri>' "
|
||||
": add a coap server resource with 'helloWorld' as content.\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps disconnect' "
|
||||
": stop dtls session with a server\r\n");
|
||||
mInterpreter.mServer->OutputFormat(">'coaps stop' "
|
||||
": stop coap secure service\r\n");
|
||||
mInterpreter.mServer->OutputFormat("\r\n legend: <>: must, (): opt "
|
||||
"\r\n");
|
||||
mInterpreter.mServer->OutputFormat("\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ProcessRequest(argc, argv);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError CoapsSecure::Stop(void)
|
||||
{
|
||||
otError error = OT_ERROR_ABORT;
|
||||
otCoapRemoveResource(mInterpreter.mInstance, &mResource);
|
||||
error = otCoapSecureStop(mInterpreter.mInstance);
|
||||
mInterpreter.mServer->OutputFormat("Coap Secure service stopped: ");
|
||||
return error;
|
||||
}
|
||||
|
||||
void OTCALL CoapsSecure::HandleClientConnect(bool aConnected, void *aContext)
|
||||
{
|
||||
static_cast<CoapsSecure *>(aContext)->HandleClientConnect(aConnected);
|
||||
}
|
||||
|
||||
void CoapsSecure::HandleClientConnect(bool aConnected)
|
||||
{
|
||||
if (aConnected)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("CoAP Secure connected!\r\n> ");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mShutdownFlag)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("CoAP Secure not connected or disconnected.\r\n> ");
|
||||
}
|
||||
else
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("CoAP Secure disconnected before stop.\r\n> ");
|
||||
if (Stop() == OT_ERROR_NONE)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat(" Done\r\n> ");
|
||||
}
|
||||
else
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat(" With error\r\n> ");
|
||||
}
|
||||
mShutdownFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
OT_UNUSED_VARIABLE(aConnected);
|
||||
}
|
||||
|
||||
void OTCALL CoapsSecure::HandleServerResponse(void * aContext,
|
||||
otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<CoapsSecure *>(aContext)->HandleServerResponse(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void CoapsSecure::HandleServerResponse(otCoapHeader *aHeader, otMessage *aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otCoapHeader responseHeader;
|
||||
otMessage * responseMessage;
|
||||
otCoapCode responseCode = OT_COAP_CODE_EMPTY;
|
||||
char responseContent[] = "helloWorld";
|
||||
|
||||
mInterpreter.mServer->OutputFormat(
|
||||
"Received coap secure request from [%x:%x:%x:%x:%x:%x:%x:%x]: ",
|
||||
HostSwap16(aMessageInfo->mSockAddr.mFields.m16[0]), HostSwap16(aMessageInfo->mSockAddr.mFields.m16[1]),
|
||||
HostSwap16(aMessageInfo->mSockAddr.mFields.m16[2]), HostSwap16(aMessageInfo->mSockAddr.mFields.m16[3]),
|
||||
HostSwap16(aMessageInfo->mSockAddr.mFields.m16[4]), HostSwap16(aMessageInfo->mSockAddr.mFields.m16[5]),
|
||||
HostSwap16(aMessageInfo->mSockAddr.mFields.m16[6]), HostSwap16(aMessageInfo->mSockAddr.mFields.m16[7]));
|
||||
|
||||
switch (otCoapHeaderGetCode(aHeader))
|
||||
{
|
||||
case OT_COAP_CODE_GET:
|
||||
mInterpreter.mServer->OutputFormat("GET");
|
||||
break;
|
||||
|
||||
case OT_COAP_CODE_DELETE:
|
||||
mInterpreter.mServer->OutputFormat("DELETE");
|
||||
break;
|
||||
|
||||
case OT_COAP_CODE_PUT:
|
||||
mInterpreter.mServer->OutputFormat("PUT");
|
||||
break;
|
||||
|
||||
case OT_COAP_CODE_POST:
|
||||
mInterpreter.mServer->OutputFormat("POST");
|
||||
break;
|
||||
|
||||
default:
|
||||
mInterpreter.mServer->OutputFormat("Undefined\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PrintPayload(aMessage);
|
||||
|
||||
if ((otCoapHeaderGetType(aHeader) == OT_COAP_TYPE_CONFIRMABLE) || otCoapHeaderGetCode(aHeader) == OT_COAP_CODE_GET)
|
||||
{
|
||||
if (otCoapHeaderGetCode(aHeader) == OT_COAP_CODE_GET)
|
||||
{
|
||||
responseCode = OT_COAP_CODE_CONTENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseCode = OT_COAP_CODE_VALID;
|
||||
}
|
||||
|
||||
otCoapHeaderInit(&responseHeader, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode);
|
||||
otCoapHeaderSetMessageId(&responseHeader, otCoapHeaderGetMessageId(aHeader));
|
||||
otCoapHeaderSetToken(&responseHeader, otCoapHeaderGetToken(aHeader), otCoapHeaderGetTokenLength(aHeader));
|
||||
|
||||
if (otCoapHeaderGetCode(aHeader) == OT_COAP_CODE_GET)
|
||||
{
|
||||
otCoapHeaderSetPayloadMarker(&responseHeader);
|
||||
}
|
||||
|
||||
responseMessage = otCoapNewMessage(mInterpreter.mInstance, &responseHeader);
|
||||
VerifyOrExit(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
if (otCoapHeaderGetCode(aHeader) == OT_COAP_CODE_GET)
|
||||
{
|
||||
SuccessOrExit(error = otMessageAppend(responseMessage, &responseContent, sizeof(responseContent)));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otCoapSecureSendResponse(mInterpreter.mInstance, responseMessage, aMessageInfo));
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE && responseMessage != NULL)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("Cannot send coap secure response message: Error %d: %s\r\n", error,
|
||||
otThreadErrorToString(error));
|
||||
otMessageFree(responseMessage);
|
||||
}
|
||||
else if (responseCode >= OT_COAP_CODE_RESPONSE_MIN)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("coap secure response sent successfully!\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
otError CoapsSecure::ProcessRequest(int argc, char *argv[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otMessage * message = NULL;
|
||||
otMessageInfo messageInfo;
|
||||
otCoapHeader header;
|
||||
uint16_t payloadLength = 0;
|
||||
uint8_t indexShifter = 0;
|
||||
|
||||
// Default parameters
|
||||
char coapUri[kMaxUriLength] = "test";
|
||||
otCoapType coapType = OT_COAP_TYPE_NON_CONFIRMABLE;
|
||||
otCoapCode coapCode = OT_COAP_CODE_GET;
|
||||
otIp6Address coapDestinationIp;
|
||||
|
||||
VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
// CoAP-Code
|
||||
if (strcmp(argv[0], "get") == 0)
|
||||
{
|
||||
coapCode = OT_COAP_CODE_GET;
|
||||
}
|
||||
else if (strcmp(argv[0], "post") == 0)
|
||||
{
|
||||
coapCode = OT_COAP_CODE_POST;
|
||||
}
|
||||
else if (strcmp(argv[0], "put") == 0)
|
||||
{
|
||||
coapCode = OT_COAP_CODE_PUT;
|
||||
}
|
||||
else if (strcmp(argv[0], "delete") == 0)
|
||||
{
|
||||
coapCode = OT_COAP_CODE_DELETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_PARSE);
|
||||
}
|
||||
|
||||
// Destination IPv6 address
|
||||
if (argc > 1)
|
||||
{
|
||||
error = otIp6AddressFromString(argv[1], &coapDestinationIp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
// Destination IPv6 address not need as client
|
||||
// if no IPv6 is entered, so ignore it and go away
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
indexShifter = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexShifter = 1;
|
||||
}
|
||||
|
||||
// CoAP-URI
|
||||
if (argc > (2 - indexShifter))
|
||||
{
|
||||
strlcpy(coapUri, argv[2 - indexShifter], kMaxUriLength);
|
||||
}
|
||||
|
||||
// CoAP-Type
|
||||
if (argc > (3 - indexShifter))
|
||||
{
|
||||
if (strcmp(argv[3 - indexShifter], "con") == 0)
|
||||
{
|
||||
coapType = OT_COAP_TYPE_CONFIRMABLE;
|
||||
}
|
||||
}
|
||||
|
||||
otCoapHeaderInit(&header, coapType, coapCode);
|
||||
otCoapHeaderGenerateToken(&header, ot::Coap::Header::kDefaultTokenLength);
|
||||
SuccessOrExit(error = otCoapHeaderAppendUriPathOptions(&header, coapUri));
|
||||
|
||||
if (argc > (4 - indexShifter))
|
||||
{
|
||||
payloadLength = static_cast<uint16_t>(strlen(argv[4 - indexShifter]));
|
||||
|
||||
if (payloadLength > 0)
|
||||
{
|
||||
otCoapHeaderSetPayloadMarker(&header);
|
||||
}
|
||||
}
|
||||
|
||||
message = otCoapNewMessage(mInterpreter.mInstance, &header);
|
||||
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
// add payload
|
||||
if (payloadLength > 0)
|
||||
{
|
||||
SuccessOrExit(error = otMessageAppend(message, argv[4 - indexShifter], payloadLength));
|
||||
}
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
messageInfo.mPeerAddr = coapDestinationIp;
|
||||
messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
|
||||
messageInfo.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
|
||||
|
||||
if ((coapType == OT_COAP_TYPE_CONFIRMABLE) || (coapCode == OT_COAP_CODE_GET))
|
||||
{
|
||||
error = otCoapSecureSendRequest(mInterpreter.mInstance, message, &CoapsSecure::HandleClientResponse, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = otCoapSecureSendRequest(mInterpreter.mInstance, message, NULL, NULL);
|
||||
}
|
||||
|
||||
mInterpreter.mServer->OutputFormat("Sending coap secure request: ");
|
||||
|
||||
exit:
|
||||
|
||||
if ((error != OT_ERROR_NONE) && (message != NULL))
|
||||
{
|
||||
otMessageFree(message);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void OTCALL CoapsSecure::HandleClientResponse(void * aContext,
|
||||
otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
otError aError)
|
||||
{
|
||||
static_cast<CoapsSecure *>(aContext)->HandleClientResponse(aHeader, aMessage, aMessageInfo, aError);
|
||||
}
|
||||
|
||||
void CoapsSecure::HandleClientResponse(otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
otError aError)
|
||||
{
|
||||
if (aError != OT_ERROR_NONE)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("Error receiving coap secure response message: Error %d: %s\r\n", aError,
|
||||
otThreadErrorToString(aError));
|
||||
}
|
||||
else
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("Received coap secure response");
|
||||
PrintHeaderInfos(aHeader);
|
||||
PrintPayload(aMessage);
|
||||
}
|
||||
|
||||
OT_UNUSED_VARIABLE(aHeader);
|
||||
OT_UNUSED_VARIABLE(aMessageInfo);
|
||||
}
|
||||
|
||||
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
void OTCALL CoapsSecure::DefaultHandle(void * aContext,
|
||||
otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<CoapsSecure *>(aContext)->DefaultHandle(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void CoapsSecure::DefaultHandle(otCoapHeader *aHeader, otMessage *aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aMessage);
|
||||
|
||||
otError error = OT_ERROR_NONE;
|
||||
otCoapHeader responseHeader;
|
||||
otMessage * responseMessage;
|
||||
|
||||
if (otCoapHeaderGetType(aHeader) == OT_COAP_TYPE_CONFIRMABLE || otCoapHeaderGetCode(aHeader) == OT_COAP_CODE_GET)
|
||||
{
|
||||
otCoapHeaderInit(&responseHeader, OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_NOT_FOUND);
|
||||
otCoapHeaderSetMessageId(&responseHeader, otCoapHeaderGetMessageId(aHeader));
|
||||
otCoapHeaderSetToken(&responseHeader, otCoapHeaderGetToken(aHeader), otCoapHeaderGetTokenLength(aHeader));
|
||||
|
||||
responseMessage = otCoapNewMessage(mInterpreter.mInstance, &responseHeader);
|
||||
VerifyOrExit(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
|
||||
SuccessOrExit(error = otCoapSecureSendResponse(mInterpreter.mInstance, responseMessage, aMessageInfo));
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
mInterpreter.mServer->OutputFormat("Default handler called.\r\n> ");
|
||||
}
|
||||
#endif // CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file contains definitions for a simple CLI CoAP Secure server and client.
|
||||
*/
|
||||
|
||||
#ifndef CLI_COAP_SECURE_HPP_
|
||||
#define CLI_COAP_SECURE_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
#include "coap/coap_header.hpp"
|
||||
#include "coap/coap_secure.hpp"
|
||||
|
||||
/**
|
||||
* to test the default handler for not handled requests set to 1.
|
||||
*/
|
||||
#define CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER 0
|
||||
|
||||
namespace ot {
|
||||
namespace Cli {
|
||||
|
||||
class Interpreter;
|
||||
|
||||
/**
|
||||
* This class implements the CLI CoAP Secure server and client.
|
||||
*
|
||||
*/
|
||||
class CoapsSecure
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] aInterpreter The CLI interpreter.
|
||||
*
|
||||
*/
|
||||
CoapsSecure(Interpreter &aInterpreter);
|
||||
|
||||
/**
|
||||
* This method interprets a list of CLI arguments.
|
||||
*
|
||||
* @param[in] argc The number of elements in argv.
|
||||
* @param[in] argv A pointer to an array of command line arguments.
|
||||
*
|
||||
*/
|
||||
otError Process(int argc, char *argv[]);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxUriLength = 32,
|
||||
kMaxBufferSize = 16,
|
||||
kPskMaxLength = 32,
|
||||
kPskIdMaxLength = 32
|
||||
};
|
||||
|
||||
void PrintHeaderInfos(otCoapHeader *aHeader) const;
|
||||
|
||||
void PrintPayload(otMessage *aMessage) const;
|
||||
|
||||
otError ProcessRequest(int argc, char *argv[]);
|
||||
|
||||
otError Stop(void);
|
||||
|
||||
static void OTCALL HandleServerResponse(void * aContext,
|
||||
otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo);
|
||||
void HandleServerResponse(otCoapHeader *aHeader, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
|
||||
static void OTCALL HandleClientResponse(void * aContext,
|
||||
otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
otError aError);
|
||||
void HandleClientResponse(otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
otError aError);
|
||||
|
||||
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
static void OTCALL DefaultHandle(void * aContext,
|
||||
otCoapHeader * aHeader,
|
||||
otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo);
|
||||
void DefaultHandle(otCoapHeader *aHeader, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
#endif // CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
|
||||
static void OTCALL HandleClientConnect(bool aConnected, void *aContext);
|
||||
void HandleClientConnect(bool aConnected);
|
||||
|
||||
otCoapResource mResource;
|
||||
char mUriPath[kMaxUriLength];
|
||||
|
||||
Interpreter &mInterpreter;
|
||||
|
||||
bool mShutdownFlag;
|
||||
bool mUseCertificate;
|
||||
uint8_t mPsk[kPskMaxLength];
|
||||
uint8_t mPskLength;
|
||||
uint8_t mPskId[kPskIdMaxLength];
|
||||
uint8_t mPskIdLength;
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
#endif // CLI_COAP_SECURE_HPP_
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file contains the X.509 certificate and private key for Application
|
||||
* CoAP Secure use with cipher suite ECDHE_ECDSA_WITH_AES_128_CCM8.
|
||||
*/
|
||||
|
||||
#ifndef SRC_CLI_X509_CERT_KEY_HPP_
|
||||
#define SRC_CLI_X509_CERT_KEY_HPP_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
|
||||
/**SERVER
|
||||
* Generate your own private key and certificate using openssl.
|
||||
*
|
||||
* 1. Generate a EC (Elliptic Curve) Private Key.
|
||||
* 'openssl ecparam -genkey -out myECKey.pem -name prime256v1 -noout'
|
||||
* 2. Generate a .X509 Certificate (Contains Public Key).
|
||||
* 'openssl req -x509 -new -key myECKey.pem -out myX509Cert.pem'
|
||||
*/
|
||||
|
||||
/**
|
||||
* place your X.509 certificate (PEM format) for ssl session
|
||||
* with ECDHE_ECDSA_WITH_AES_128_CCM_8 here.
|
||||
*/
|
||||
#define OT_CLI_COAPS_X509_CERT \
|
||||
"-----BEGIN CERTIFICATE-----\r\n" \
|
||||
"MIIBrTCCAVICBgDRArfDJTAKBggqhkjOPQQDAjBcMQswCQYDVQQGEwJaWTESMBAG\r\n" \
|
||||
"A1UECAwJWW91clN0YXRlMRAwDgYDVQQKDAdZb3VyT3JnMRQwEgYDVQQLDAtZb3Vy\r\n" \
|
||||
"T3JnVW5pdDERMA8GA1UEAwwIVmVuZG9yQ0EwIBcNMTgwNzEzMTIzNzA3WhgPMjI5\r\n" \
|
||||
"MjA0MjYxMjM3MDdaMGExCzAJBgNVBAYTAlpZMRIwEAYDVQQIDAlZb3VyU3RhdGUx\r\n" \
|
||||
"EDAOBgNVBAoMB1lvdXJPcmcxFDASBgNVBAsMC1lvdXJPcmdVbml0MRYwFAYDVQQD\r\n" \
|
||||
"DA1QWEMzLkU3NS0xMDBBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIUtlV99w\r\n" \
|
||||
"OggiASflg6CVsGMzXMXYrNgQ1piLIybCkrq+YoqJ3mwcbJHWlvxGPxNIQw6i8kzK\r\n" \
|
||||
"bkC642ZWgBT5MzAKBggqhkjOPQQDAgNJADBGAiEA/1yk69A+37kLBvdOWPDRXGwe\r\n" \
|
||||
"0AoICTGaLqzB3cF5mtACIQC28WwmzHb5gqe3nOPAM73py1v17EXZj07PU89BAEcb\r\n" \
|
||||
"yg==\r\n" \
|
||||
"-----END CERTIFICATE-----\r\n"
|
||||
|
||||
/**
|
||||
* place your private key (PEM format) for ssl session
|
||||
* with ECDHE_ECDSA_WITH_AES_128_CCM_8 here.
|
||||
*/
|
||||
#define OT_CLI_COAPS_PRIV_KEY \
|
||||
"-----BEGIN EC PRIVATE KEY-----\r\n" \
|
||||
"MHcCAQEEIFYQh2R7M48qOHePw+VE4b034UlZmWWC/iNAK34sQbucoAoGCCqGSM49\r\n" \
|
||||
"AwEHoUQDQgAEIUtlV99wOggiASflg6CVsGMzXMXYrNgQ1piLIybCkrq+YoqJ3mwc\r\n" \
|
||||
"bJHWlvxGPxNIQw6i8kzKbkC642ZWgBT5Mw==\r\n" \
|
||||
"-----END EC PRIVATE KEY-----\r\n"
|
||||
|
||||
/**
|
||||
* Place peers CA certificate (PEM format) here.
|
||||
* It's necessary to validate the peers certificate. If you haven't a
|
||||
* CA certificate, you must run the coaps without checking certificate.
|
||||
*/
|
||||
#define OT_CLI_COAPS_TRUSTED_ROOT_CERTIFICATE \
|
||||
"-----BEGIN CERTIFICATE-----\r\n" \
|
||||
"MIICDzCCAbWgAwIBAgIESZYC0jAKBggqhkjOPQQDAjBcMQswCQYDVQQGEwJaWTES\r\n" \
|
||||
"MBAGA1UECAwJWW91clN0YXRlMRAwDgYDVQQKDAdZb3VyT3JnMRQwEgYDVQQLDAtZ\r\n" \
|
||||
"b3VyT3JnVW5pdDERMA8GA1UEAwwIVmVuZG9yQ0EwIBcNMTgwNzEzMTE1NjA5WhgP\r\n" \
|
||||
"MjI5MjA0MjYxMTU2MDlaMFwxCzAJBgNVBAYTAlpZMRIwEAYDVQQIDAlZb3VyU3Rh\r\n" \
|
||||
"dGUxEDAOBgNVBAoMB1lvdXJPcmcxFDASBgNVBAsMC1lvdXJPcmdVbml0MREwDwYD\r\n" \
|
||||
"VQQDDAhWZW5kb3JDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGAAuYcBIgP0\r\n" \
|
||||
"fMC1Bd+1nAH5S1goR0TaDAIadK4hULQr5LwziuDk9XTQaOTwmWB9iR1eiHC6RY8W\r\n" \
|
||||
"wyrGBbnEbzujYzBhMB0GA1UdDgQWBBQ+yCpIszhzbmXe2At1GofREjnBxjAfBgNV\r\n" \
|
||||
"HSMEGDAWgBQ+yCpIszhzbmXe2At1GofREjnBxjAPBgNVHRMBAf8EBTADAQH/MA4G\r\n" \
|
||||
"A1UdDwEB/wQEAwIBhjAKBggqhkjOPQQDAgNIADBFAiBW60XgdSRD24rbTgdneS+V\r\n" \
|
||||
"SHVix8LuXunPYW50LmxbrwIhAOw4gMroRIOS26y0TcND03FnyO3wBNF9MjM0hWKQ\r\n" \
|
||||
"JXk3\r\n" \
|
||||
"-----END CERTIFICATE-----\r\n" \
|
||||
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* SRC_CLI_X509_CERT_KEY_HPP_ */
|
||||
@@ -107,6 +107,7 @@ SOURCES_COMMON = \
|
||||
api/channel_monitor_api.cpp \
|
||||
api/child_supervision_api.cpp \
|
||||
api/coap_api.cpp \
|
||||
api/coap_secure_api.cpp \
|
||||
api/commissioner_api.cpp \
|
||||
api/crypto_api.cpp \
|
||||
api/dataset_api.cpp \
|
||||
|
||||
@@ -113,6 +113,11 @@ otCoapCode otCoapHeaderGetCode(const otCoapHeader *aHeader)
|
||||
return static_cast<const Coap::Header *>(aHeader)->GetCode();
|
||||
}
|
||||
|
||||
const char *otCoapHeaderCodeToString(const otCoapHeader *aHeader)
|
||||
{
|
||||
return static_cast<const Coap::Header *>(aHeader)->CodeToString();
|
||||
}
|
||||
|
||||
uint16_t otCoapHeaderGetMessageId(const otCoapHeader *aHeader)
|
||||
{
|
||||
return static_cast<const Coap::Header *>(aHeader)->GetMessageId();
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2018, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the OpenThread CoAP Secure API.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/coap_secure.h>
|
||||
|
||||
#include "coap/coap_header.hpp"
|
||||
#include "coap/coap_secure.hpp"
|
||||
#include "common/instance.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
using namespace ot;
|
||||
|
||||
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort, void *aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().Start(aPort, NULL, aContext);
|
||||
}
|
||||
|
||||
otError otCoapSecureSetCertificate(otInstance * aInstance,
|
||||
const uint8_t *aX509Cert,
|
||||
uint32_t aX509Length,
|
||||
const uint8_t *aPrivateKey,
|
||||
uint32_t aPrivateKeyLength)
|
||||
{
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
if (aX509Cert == NULL || aX509Length == 0 || aPrivateKey == NULL || aPrivateKeyLength == 0)
|
||||
{
|
||||
return OT_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
return instance.GetApplicationCoapSecure().SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aX509Cert);
|
||||
OT_UNUSED_VARIABLE(aX509Length);
|
||||
OT_UNUSED_VARIABLE(aPrivateKey);
|
||||
OT_UNUSED_VARIABLE(aPrivateKeyLength);
|
||||
|
||||
return OT_ERROR_DISABLED_FEATURE;
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
}
|
||||
|
||||
otError otCoapSecureSetCaCertificateChain(otInstance * aInstance,
|
||||
const uint8_t *aX509CaCertificateChain,
|
||||
uint32_t aX509CaCertChainLength)
|
||||
{
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
if (aX509CaCertificateChain == NULL || aX509CaCertChainLength == 0)
|
||||
{
|
||||
return OT_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
return instance.GetApplicationCoapSecure().SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aX509CaCertificateChain);
|
||||
OT_UNUSED_VARIABLE(aX509CaCertChainLength);
|
||||
|
||||
return OT_ERROR_DISABLED_FEATURE;
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
}
|
||||
|
||||
otError otCoapSecureSetPsk(otInstance * aInstance,
|
||||
const uint8_t *aPsk,
|
||||
uint16_t aPskLength,
|
||||
const uint8_t *aPskIdentity,
|
||||
uint16_t aPskIdLength)
|
||||
{
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
if (aPsk == NULL || aPskLength == 0 || aPskIdentity == NULL || aPskIdLength == 0)
|
||||
{
|
||||
return OT_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
||||
return instance.GetApplicationCoapSecure().SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength);
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aPsk);
|
||||
OT_UNUSED_VARIABLE(aPskLength);
|
||||
OT_UNUSED_VARIABLE(aPskIdentity);
|
||||
OT_UNUSED_VARIABLE(aPskIdLength);
|
||||
|
||||
return OT_ERROR_DISABLED_FEATURE;
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
}
|
||||
|
||||
otError otCoapSecureGetPeerCertificateBase64(otInstance * aInstance,
|
||||
unsigned char *aPeerCert,
|
||||
uint64_t * aCertLength,
|
||||
uint64_t aCertBufferSize)
|
||||
{
|
||||
#ifdef MBEDTLS_BASE64_C
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().GetPeerCertificateBase64(aPeerCert, (size_t *)aCertLength,
|
||||
(size_t)aCertBufferSize);
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aPeerCert);
|
||||
OT_UNUSED_VARIABLE(aCertLength);
|
||||
OT_UNUSED_VARIABLE(aCertBufferSize);
|
||||
|
||||
return OT_ERROR_DISABLED_FEATURE;
|
||||
#endif // MBEDTLS_BASE64_C
|
||||
}
|
||||
|
||||
void otCoapSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.GetApplicationCoapSecure().SetSslAuthMode(aVerifyPeerCertificate);
|
||||
}
|
||||
|
||||
otError otCoapSecureConnect(otInstance * aInstance,
|
||||
const otMessageInfo * aMessageInfo,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void * aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().Connect(*static_cast<const Ip6::MessageInfo *>(aMessageInfo), aHandler,
|
||||
aContext);
|
||||
}
|
||||
|
||||
otError otCoapSecureDisconnect(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().Disconnect();
|
||||
}
|
||||
|
||||
bool otCoapSecureIsConnected(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().IsConnected();
|
||||
}
|
||||
|
||||
bool otCoapSecureIsConncetionActive(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().IsConnectionActive();
|
||||
}
|
||||
|
||||
otError otCoapSecureStop(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().Stop();
|
||||
}
|
||||
|
||||
otError otCoapSecureSendRequest(otInstance * aInstance,
|
||||
otMessage * aMessage,
|
||||
otCoapResponseHandler aHandler = NULL,
|
||||
void * aContext = NULL)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().SendMessage(*static_cast<Message *>(aMessage), aHandler, aContext);
|
||||
}
|
||||
|
||||
otError otCoapSecureAddResource(otInstance *aInstance, otCoapResource *aResource)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().AddResource(*static_cast<Coap::Resource *>(aResource));
|
||||
}
|
||||
|
||||
void otCoapSecureRemoveResource(otInstance *aInstance, otCoapResource *aResource)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.GetApplicationCoapSecure().RemoveResource(*static_cast<Coap::Resource *>(aResource));
|
||||
}
|
||||
|
||||
void otCoapSecureSetClientConnectedCallback(otInstance * aInstance,
|
||||
otHandleCoapSecureClientConnect aHandler,
|
||||
void * aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.GetApplicationCoapSecure().SetClientConnectedCallback(aHandler, aContext);
|
||||
}
|
||||
|
||||
void otCoapSecureSetDefaultHandler(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.GetApplicationCoapSecure().SetDefaultHandler(aHandler, aContext);
|
||||
}
|
||||
|
||||
otError otCoapSecureSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().SendMessage(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
@@ -432,5 +432,102 @@ void Header::SetDefaultResponseHeader(const Header &aRequestHeader)
|
||||
SetToken(aRequestHeader.GetToken(), aRequestHeader.GetTokenLength());
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
const char *Header::CodeToString(void) const
|
||||
{
|
||||
const char *mCodeString;
|
||||
|
||||
switch (mHeader.mFields.mCode)
|
||||
{
|
||||
case OT_COAP_CODE_INTERNAL_ERROR:
|
||||
mCodeString = "InternalError";
|
||||
break;
|
||||
case OT_COAP_CODE_METHOD_NOT_ALLOWED:
|
||||
mCodeString = "MethodNotAllowed";
|
||||
break;
|
||||
case OT_COAP_CODE_CONTENT:
|
||||
mCodeString = "Content";
|
||||
break;
|
||||
case OT_COAP_CODE_EMPTY:
|
||||
mCodeString = "Empty";
|
||||
break;
|
||||
case OT_COAP_CODE_GET:
|
||||
mCodeString = "Get";
|
||||
break;
|
||||
case OT_COAP_CODE_POST:
|
||||
mCodeString = "Post";
|
||||
break;
|
||||
case OT_COAP_CODE_PUT:
|
||||
mCodeString = "Put";
|
||||
break;
|
||||
case OT_COAP_CODE_DELETE:
|
||||
mCodeString = "Delete";
|
||||
break;
|
||||
case OT_COAP_CODE_NOT_FOUND:
|
||||
mCodeString = "NotFound";
|
||||
break;
|
||||
case OT_COAP_CODE_UNSUPPORTED_FORMAT:
|
||||
mCodeString = "UnsupportedFormat";
|
||||
break;
|
||||
case OT_COAP_CODE_RESPONSE_MIN:
|
||||
mCodeString = "ResponseMin";
|
||||
break;
|
||||
case OT_COAP_CODE_CREATED:
|
||||
mCodeString = "Created";
|
||||
break;
|
||||
case OT_COAP_CODE_DELETED:
|
||||
mCodeString = "Deleted";
|
||||
break;
|
||||
case OT_COAP_CODE_VALID:
|
||||
mCodeString = "Valid";
|
||||
break;
|
||||
case OT_COAP_CODE_CHANGED:
|
||||
mCodeString = "Changed";
|
||||
break;
|
||||
case OT_COAP_CODE_BAD_REQUEST:
|
||||
mCodeString = "BadRequest";
|
||||
break;
|
||||
case OT_COAP_CODE_UNAUTHORIZED:
|
||||
mCodeString = "Unauthorized";
|
||||
break;
|
||||
case OT_COAP_CODE_BAD_OPTION:
|
||||
mCodeString = "BadOption";
|
||||
break;
|
||||
case OT_COAP_CODE_FORBIDDEN:
|
||||
mCodeString = "Forbidden";
|
||||
break;
|
||||
case OT_COAP_CODE_NOT_ACCEPTABLE:
|
||||
mCodeString = "NotAcceptable";
|
||||
break;
|
||||
case OT_COAP_CODE_PRECONDITION_FAILED:
|
||||
mCodeString = "PreconditionFailed";
|
||||
break;
|
||||
case OT_COAP_CODE_REQUEST_TOO_LARGE:
|
||||
mCodeString = "RequestTooLarge";
|
||||
break;
|
||||
case OT_COAP_CODE_NOT_IMPLEMENTED:
|
||||
mCodeString = "NotImplemented";
|
||||
break;
|
||||
case OT_COAP_CODE_BAD_GATEWAY:
|
||||
mCodeString = "BadGateway";
|
||||
break;
|
||||
case OT_COAP_CODE_SERVICE_UNAVAILABLE:
|
||||
mCodeString = "ServiceUnavailable";
|
||||
break;
|
||||
case OT_COAP_CODE_GATEWAY_TIMEOUT:
|
||||
mCodeString = "GatewayTimeout";
|
||||
break;
|
||||
case OT_COAP_CODE_PROXY_NOT_SUPPORTED:
|
||||
mCodeString = "ProxyNotSupported";
|
||||
break;
|
||||
default:
|
||||
mCodeString = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return mCodeString;
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace ot
|
||||
|
||||
@@ -175,6 +175,16 @@ public:
|
||||
*/
|
||||
void SetCode(Code aCode) { mHeader.mFields.mCode = static_cast<uint8_t>(aCode); }
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
/**
|
||||
* This method returns the CoAP Code as human readable string.
|
||||
*
|
||||
* @ returns The CoAP Code as string.
|
||||
*
|
||||
*/
|
||||
const char *CodeToString(void) const;
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
|
||||
/**
|
||||
* This method returns the Message ID value.
|
||||
*
|
||||
|
||||
@@ -54,9 +54,27 @@ CoapSecure::CoapSecure(Instance &aInstance)
|
||||
, mTransportContext(NULL)
|
||||
, mTransmitMessage(NULL)
|
||||
, mTransmitTask(aInstance, &CoapSecure::HandleUdpTransmit, this)
|
||||
, mLayerTwoSecurity(false)
|
||||
{
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
CoapSecure::CoapSecure(Instance & aInstance,
|
||||
Tasklet::Handler aUdpTransmitHandle,
|
||||
Timer::Handler aRetransmissionTimer,
|
||||
Timer::Handler aResponsesQueueTimer)
|
||||
: CoapBase(aInstance, aRetransmissionTimer, aResponsesQueueTimer)
|
||||
, mConnectedCallback(NULL)
|
||||
, mConnectedContext(NULL)
|
||||
, mTransportCallback(NULL)
|
||||
, mTransportContext(NULL)
|
||||
, mTransmitMessage(NULL)
|
||||
, mTransmitTask(aInstance, aUdpTransmitHandle, this)
|
||||
, mLayerTwoSecurity(true)
|
||||
{
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
otError CoapSecure::Start(uint16_t aPort, TransportCallback aCallback, void *aContext)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -135,6 +153,53 @@ otError CoapSecure::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
|
||||
return GetNetif().GetDtls().SetPsk(aPsk, aPskLength);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
otError CoapSecure::SetCertificate(const uint8_t *aX509Cert,
|
||||
uint32_t aX509Length,
|
||||
const uint8_t *aPrivateKey,
|
||||
uint32_t aPrivateKeyLength)
|
||||
{
|
||||
return GetNetif().GetDtls().SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
|
||||
}
|
||||
|
||||
otError CoapSecure::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLenth)
|
||||
{
|
||||
return GetNetif().GetDtls().SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLenth);
|
||||
}
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
otError CoapSecure::SetPreSharedKey(const uint8_t *aPsk,
|
||||
uint16_t aPskLength,
|
||||
const uint8_t *aPskIdentity,
|
||||
uint16_t aPskIdLength)
|
||||
{
|
||||
return GetNetif().GetDtls().SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength);
|
||||
}
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_BASE64_C
|
||||
otError CoapSecure::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize)
|
||||
{
|
||||
return GetNetif().GetDtls().GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize);
|
||||
}
|
||||
#endif // MBEDTLS_BASE64_C
|
||||
|
||||
void CoapSecure::SetClientConnectedCallback(ConnectedCallback aCallback, void *aContext)
|
||||
{
|
||||
mConnectedCallback = aCallback;
|
||||
mConnectedContext = aContext;
|
||||
}
|
||||
|
||||
void CoapSecure::SetSslAuthMode(bool aVerifyPeerCertificate)
|
||||
{
|
||||
GetNetif().GetDtls().SetSslAuthMode(aVerifyPeerCertificate);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
otError CoapSecure::SendMessage(Message &aMessage, otCoapResponseHandler aHandler, void *aContext)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -183,8 +248,8 @@ void CoapSecure::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo
|
||||
|
||||
mPeerAddress.SetSockPort(aMessageInfo.GetSockPort());
|
||||
|
||||
netif.GetDtls().Start(false, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive,
|
||||
CoapSecure::HandleDtlsSend, this);
|
||||
VerifyOrExit(netif.GetDtls().Start(false, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive,
|
||||
CoapSecure::HandleDtlsSend, this) == OT_ERROR_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -248,7 +313,7 @@ otError CoapSecure::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_
|
||||
{
|
||||
VerifyOrExit((mTransmitMessage = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
mTransmitMessage->SetSubType(aMessageSubType);
|
||||
mTransmitMessage->SetLinkSecurityEnabled(false);
|
||||
mTransmitMessage->SetLinkSecurityEnabled(mLayerTwoSecurity);
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mTransmitMessage->Append(aBuf, aLength));
|
||||
@@ -312,6 +377,33 @@ void CoapSecure::HandleResponsesQueueTimer(Timer &aTimer)
|
||||
aTimer.GetOwner<CoapSecure>().CoapBase::HandleResponsesQueueTimer();
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
ApplicationCoapSecure::ApplicationCoapSecure(Instance &aInstance)
|
||||
: CoapSecure(aInstance,
|
||||
&ApplicationCoapSecure::HandleUdpTransmit,
|
||||
&ApplicationCoapSecure::HandleRetransmissionTimer,
|
||||
&ApplicationCoapSecure::HandleResponsesQueueTimer)
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationCoapSecure::HandleUdpTransmit(Tasklet &aTasklet)
|
||||
{
|
||||
aTasklet.GetOwner<ApplicationCoapSecure>().CoapSecure::HandleUdpTransmit();
|
||||
}
|
||||
|
||||
void ApplicationCoapSecure::HandleRetransmissionTimer(Timer &aTimer)
|
||||
{
|
||||
aTimer.GetOwner<ApplicationCoapSecure>().CoapBase::HandleRetransmissionTimer();
|
||||
}
|
||||
|
||||
void ApplicationCoapSecure::HandleResponsesQueueTimer(Timer &aTimer)
|
||||
{
|
||||
aTimer.GetOwner<ApplicationCoapSecure>().CoapBase::HandleResponsesQueueTimer();
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "coap/coap.hpp"
|
||||
#include "meshcop/dtls.hpp"
|
||||
|
||||
#include <openthread/coap_secure.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for the secure CoAP agent.
|
||||
@@ -73,6 +75,23 @@ public:
|
||||
*/
|
||||
explicit CoapSecure(Instance &aInstance);
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
* (Used for Application CoAPS)
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
* @param[in] aUdpTransmitHandle Handler for udp transmit.
|
||||
* @param[in] aRetransmissionTimer Handler for retransmission.
|
||||
* @param[in] aResponsesQueueTimer Handler for Queue Responses.
|
||||
*
|
||||
*/
|
||||
explicit CoapSecure(Instance & aInstance,
|
||||
Tasklet::Handler aUdpTransmitHandle,
|
||||
Timer::Handler aRetransmissionTimer,
|
||||
Timer::Handler aResponsesQueueTimer);
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* This method starts the secure CoAP agent.
|
||||
*
|
||||
@@ -106,8 +125,9 @@ public:
|
||||
/**
|
||||
* This method initializes DTLS session with a peer.
|
||||
*
|
||||
* @param[in] aMessageInfo A reference to an address of the peer.
|
||||
* @param[in] aCallback A pointer to a function that will be called once DTLS connection is established.
|
||||
* @param[in] aMessageInfo A pointer to a message info structure.
|
||||
* @param[in] aCallback A pointer to a function that will be called once DTLS connection is
|
||||
* established.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started DTLS connection.
|
||||
*
|
||||
@@ -160,6 +180,101 @@ public:
|
||||
*/
|
||||
otError SetPsk(const uint8_t *aPsk, uint8_t aPskLength);
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
/**
|
||||
* This method sets the Pre Shared Key (PSK) for DTLS sessions
|
||||
* identified by a PSK.
|
||||
* DTLS mode "TLS with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[in] aPsk A pointer to the PSK.
|
||||
* @param[in] aPskLength The PSK char length.
|
||||
* @param[in] aPskIdentity The Identity Name for the PSK.
|
||||
* @param[in] aPskIdLength The PSK Identity Length.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the PSK.
|
||||
*
|
||||
*/
|
||||
otError SetPreSharedKey(const uint8_t *aPsk,
|
||||
uint16_t aPskLength,
|
||||
const uint8_t *aPskIdentity,
|
||||
uint16_t aPskIdLength);
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
/**
|
||||
* This method sets a X509 certificate with corresponding private key for DTLS session.
|
||||
*
|
||||
* DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[in] aX509Certificate A pointer to the PEM formatted X509 PEM certificate.
|
||||
* @param[in] aX509CertLength The length of certificate.
|
||||
* @param[in] aPrivateKey A pointer to the PEM formatted private key.
|
||||
* @param[in] aPrivateKeyLength The length of the private key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the x509 certificate with his private key.
|
||||
*
|
||||
*/
|
||||
otError SetCertificate(const uint8_t *aX509Cert,
|
||||
uint32_t aX509Length,
|
||||
const uint8_t *aPrivateKey,
|
||||
uint32_t aPrivateKeyLength);
|
||||
|
||||
/**
|
||||
* This method sets the trusted top level CAs. It is needed for validate the
|
||||
* certificate of the peer.
|
||||
*
|
||||
* DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain.
|
||||
* @param[in] aX509CaCertChainLength The length of chain.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the the trusted top level CAs.
|
||||
*
|
||||
*/
|
||||
otError SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength);
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_BASE64_C
|
||||
/**
|
||||
* This method returns the peer x509 certificate base64 encoded.
|
||||
*
|
||||
* DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[out] aPeerCert A pointer to the base64 encoded certificate buffer.
|
||||
* @param[out] aCertLength The length of the base64 encoded peer certificate.
|
||||
* @param[in] aCertBufferSize The buffer size of aPeerCert.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully get the peer certificate.
|
||||
* @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate.
|
||||
*
|
||||
*/
|
||||
otError GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize);
|
||||
#endif // MBEDTLS_BASE64_C
|
||||
|
||||
/**
|
||||
* This method sets the connected callback to indicate, when
|
||||
* a Client connect to the CoAP Secure server.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function that will be called once DTLS connection is
|
||||
* established.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
void SetClientConnectedCallback(ConnectedCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method set the authentication mode for the coap secure connection.
|
||||
* Disable or enable the verification of peer certificate.
|
||||
*
|
||||
* @param[in] aVerifyPeerCertificate true, if the peer certificate should verify.
|
||||
*
|
||||
*/
|
||||
void SetSslAuthMode(bool aVerifyPeerCertificate);
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* This method sends a CoAP message over secure DTLS connection.
|
||||
*
|
||||
@@ -218,6 +333,9 @@ public:
|
||||
*/
|
||||
const Ip6::MessageInfo &GetPeerMessageInfo(void) const { return mPeerAddress; }
|
||||
|
||||
protected:
|
||||
void HandleUdpTransmit(void);
|
||||
|
||||
private:
|
||||
virtual otError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
@@ -231,7 +349,6 @@ private:
|
||||
otError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
|
||||
|
||||
static void HandleUdpTransmit(Tasklet &aTasklet);
|
||||
void HandleUdpTransmit(void);
|
||||
|
||||
static void HandleRetransmissionTimer(Timer &aTimer);
|
||||
static void HandleResponsesQueueTimer(Timer &aTimer);
|
||||
@@ -243,8 +360,35 @@ private:
|
||||
void * mTransportContext;
|
||||
Message * mTransmitMessage;
|
||||
Tasklet mTransmitTask;
|
||||
|
||||
bool mLayerTwoSecurity : 1;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* This class implements the application CoAP Secure client and server.
|
||||
*
|
||||
*/
|
||||
class ApplicationCoapSecure : public CoapSecure
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit ApplicationCoapSecure(Instance &aInstance);
|
||||
|
||||
private:
|
||||
static void HandleRetransmissionTimer(Timer &aTimer);
|
||||
static void HandleResponsesQueueTimer(Timer &aTimer);
|
||||
static void HandleUdpTransmit(Tasklet &aTasklet);
|
||||
};
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ Instance::Instance(void)
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
, mApplicationCoap(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
, mApplicationCoapSecure(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_CHANNEL_MONITOR
|
||||
, mChannelMonitor(*this)
|
||||
#endif
|
||||
|
||||
@@ -328,6 +328,16 @@ public:
|
||||
Coap::ApplicationCoap &GetApplicationCoap(void) { return mApplicationCoap; }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* This method returns a reference to application COAP Secure object.
|
||||
*
|
||||
* @returns A reference to the application COAP Secure object.
|
||||
*
|
||||
*/
|
||||
Coap::ApplicationCoapSecure &GetApplicationCoapSecure(void) { return mApplicationCoapSecure; }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_CHANNEL_MONITOR
|
||||
/**
|
||||
* This method returns a reference to ChannelMonitor object.
|
||||
@@ -426,6 +436,10 @@ private:
|
||||
Coap::ApplicationCoap mApplicationCoap;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
Coap::ApplicationCoapSecure mApplicationCoapSecure;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_CHANNEL_MONITOR
|
||||
Utils::ChannelMonitor mChannelMonitor;
|
||||
#endif
|
||||
@@ -571,6 +585,13 @@ template <> inline Coap::ApplicationCoap &Instance::Get(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
template <> inline Coap::ApplicationCoapSecure &Instance::Get(void)
|
||||
{
|
||||
return GetApplicationCoapSecure();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
template <> inline MeshCoP::Commissioner &Instance::Get(void)
|
||||
{
|
||||
|
||||
+382
-29
@@ -56,6 +56,7 @@ namespace MeshCoP {
|
||||
Dtls::Dtls(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mPskLength(0)
|
||||
, mVerifyPeerCertificate(true)
|
||||
, mStarted(false)
|
||||
, mTimer(aInstance, &Dtls::HandleTimer, this)
|
||||
, mTimerIntermediate(0)
|
||||
@@ -68,15 +69,42 @@ Dtls::Dtls(Instance &aInstance)
|
||||
, mSendHandler(NULL)
|
||||
, mContext(NULL)
|
||||
, mClient(false)
|
||||
, mGuardTimerSet(false)
|
||||
, mMessageSubType(Message::kSubTypeNone)
|
||||
, mMessageDefaultSubType(Message::kSubTypeNone)
|
||||
{
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
mPreSharedKey = NULL;
|
||||
mPreSharedKeyIdentity = NULL;
|
||||
mPreSharedKeyIdLength = 0;
|
||||
mPreSharedKeyLength = 0;
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
mCaChainSrc = NULL;
|
||||
mCaChainLength = 0;
|
||||
mOwnCertSrc = NULL;
|
||||
mOwnCertLength = 0;
|
||||
mPrivateKeySrc = NULL;
|
||||
mPrivateKeyLength = 0;
|
||||
memset(&mCaChain, 0, sizeof(mCaChain));
|
||||
memset(&mOwnCert, 0, sizeof(mOwnCert));
|
||||
memset(&mPrivateKey, 0, sizeof(mPrivateKey));
|
||||
mbedtls_x509_crt_init(&mCaChain);
|
||||
mbedtls_x509_crt_init(&mOwnCert);
|
||||
mbedtls_pk_init(&mPrivateKey);
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
memset(mCipherSuites, 0, sizeof(mCipherSuites));
|
||||
memset(mPsk, 0, sizeof(mPsk));
|
||||
memset(&mEntropy, 0, sizeof(mEntropy));
|
||||
memset(&mCtrDrbg, 0, sizeof(mCtrDrbg));
|
||||
memset(&mSsl, 0, sizeof(mSsl));
|
||||
memset(&mConf, 0, sizeof(mConf));
|
||||
memset(&mCookieCtx, 0, sizeof(mCookieCtx));
|
||||
|
||||
mProvisioningUrl.Init();
|
||||
}
|
||||
|
||||
@@ -111,9 +139,8 @@ otError Dtls::Start(bool aClient,
|
||||
SendHandler aSendHandler,
|
||||
void * aContext)
|
||||
{
|
||||
static const int ciphersuites[2] = {0xC0FF, 0}; // EC-JPAKE cipher suite
|
||||
otExtAddress eui64;
|
||||
int rval;
|
||||
otExtAddress eui64;
|
||||
int rval;
|
||||
|
||||
mConnectedHandler = aConnectedHandler;
|
||||
mReceiveHandler = aReceiveHandler;
|
||||
@@ -123,6 +150,9 @@ otError Dtls::Start(bool aClient,
|
||||
mReceiveMessage = NULL;
|
||||
mMessageSubType = Message::kSubTypeNone;
|
||||
|
||||
// do not handle new connection before guard time expired
|
||||
VerifyOrExit(mGuardTimerSet == false, rval = MBEDTLS_ERR_SSL_TIMEOUT);
|
||||
|
||||
mbedtls_ssl_init(&mSsl);
|
||||
mbedtls_ssl_config_init(&mConf);
|
||||
mbedtls_ctr_drbg_init(&mCtrDrbg);
|
||||
@@ -141,10 +171,23 @@ otError Dtls::Start(bool aClient,
|
||||
MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
VerifyOrExit(rval == 0);
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
if (mVerifyPeerCertificate && mCipherSuites[0] == MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8)
|
||||
{
|
||||
mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
}
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(mVerifyPeerCertificate);
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, &mCtrDrbg);
|
||||
mbedtls_ssl_conf_min_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
mbedtls_ssl_conf_max_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
mbedtls_ssl_conf_ciphersuites(&mConf, ciphersuites);
|
||||
mbedtls_ssl_conf_ciphersuites(&mConf, mCipherSuites);
|
||||
mbedtls_ssl_conf_export_keys_cb(&mConf, HandleMbedtlsExportKeys, this);
|
||||
mbedtls_ssl_conf_handshake_timeout(&mConf, 8000, 60000);
|
||||
mbedtls_ssl_conf_dbg(&mConf, HandleMbedtlsDebug, this);
|
||||
@@ -165,29 +208,108 @@ otError Dtls::Start(bool aClient,
|
||||
mbedtls_ssl_set_bio(&mSsl, this, &Dtls::HandleMbedtlsTransmit, HandleMbedtlsReceive, NULL);
|
||||
mbedtls_ssl_set_timer_cb(&mSsl, this, &Dtls::HandleMbedtlsSetTimer, HandleMbedtlsGetTimer);
|
||||
|
||||
rval = mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
rval = mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
rval = SetApplicationCoapSecureKeys();
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
VerifyOrExit(rval == 0);
|
||||
|
||||
mStarted = true;
|
||||
Process();
|
||||
|
||||
otLogInfoMeshCoP(GetInstance(), "DTLS started");
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
otLogInfoMeshCoP(GetInstance(), "DTLS started");
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
otLogInfoCoap(GetInstance(), "Application Coap Secure DTLS started");
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
exit:
|
||||
return MapError(rval);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
int Dtls::SetApplicationCoapSecureKeys(void)
|
||||
{
|
||||
int rval = 0;
|
||||
|
||||
VerifyOrExit(&mCipherSuites[0] != NULL, rval = MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
|
||||
|
||||
switch (mCipherSuites[0])
|
||||
{
|
||||
case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
if (mCaChainSrc != NULL)
|
||||
{
|
||||
rval = mbedtls_x509_crt_parse(&mCaChain, (const unsigned char *)mCaChainSrc, (size_t)mCaChainLength);
|
||||
VerifyOrExit(rval == 0);
|
||||
mbedtls_ssl_conf_ca_chain(&mConf, &mCaChain, NULL);
|
||||
}
|
||||
|
||||
if (mOwnCertSrc != NULL && mPrivateKeySrc != NULL)
|
||||
{
|
||||
rval = mbedtls_x509_crt_parse(&mOwnCert, (const unsigned char *)mOwnCertSrc, (size_t)mOwnCertLength);
|
||||
VerifyOrExit(rval == 0);
|
||||
rval = mbedtls_pk_parse_key(&mPrivateKey, (const unsigned char *)mPrivateKeySrc, (size_t)mPrivateKeyLength,
|
||||
NULL, 0);
|
||||
VerifyOrExit(rval == 0);
|
||||
rval = mbedtls_ssl_conf_own_cert(&mConf, &mOwnCert, &mPrivateKey);
|
||||
VerifyOrExit(rval == 0);
|
||||
}
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
break;
|
||||
|
||||
case MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8:
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
rval = mbedtls_ssl_conf_psk(&mConf, (unsigned char *)mPreSharedKey, mPreSharedKeyLength,
|
||||
(unsigned char *)mPreSharedKeyIdentity, mPreSharedKeyIdLength);
|
||||
VerifyOrExit(rval == 0);
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
break;
|
||||
|
||||
default:
|
||||
otLogCritCoap(GetInstance(), "Application Coap Secure DTLS: Not supported cipher.");
|
||||
rval = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
ExitNow();
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
void Dtls::SetSslAuthMode(bool aVerifyPeerCertificate)
|
||||
{
|
||||
mVerifyPeerCertificate = aVerifyPeerCertificate;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
otError Dtls::Stop(void)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&mSsl);
|
||||
Close();
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
void Dtls::Close(void)
|
||||
{
|
||||
// guard time, that the possible close notify
|
||||
// not open an invalid (new) connection
|
||||
mGuardTimerSet = true;
|
||||
mTimer.Start(kGuardTimeNewConnectionMilli);
|
||||
VerifyOrExit(mStarted);
|
||||
|
||||
mStarted = false;
|
||||
mbedtls_ssl_free(&mSsl);
|
||||
mbedtls_ssl_config_free(&mConf);
|
||||
@@ -195,6 +317,14 @@ void Dtls::Close(void)
|
||||
mbedtls_entropy_free(&mEntropy);
|
||||
mbedtls_ssl_cookie_free(&mCookieCtx);
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
mbedtls_x509_crt_free(&mCaChain);
|
||||
mbedtls_x509_crt_free(&mOwnCert);
|
||||
mbedtls_pk_free(&mPrivateKey);
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
if (mConnectedHandler != NULL)
|
||||
{
|
||||
mConnectedHandler(mContext, false);
|
||||
@@ -216,12 +346,101 @@ otError Dtls::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
|
||||
VerifyOrExit(aPskLength <= sizeof(mPsk), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
memcpy(mPsk, aPsk, aPskLength);
|
||||
mPskLength = aPskLength;
|
||||
mPskLength = aPskLength;
|
||||
mCipherSuites[0] = MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8;
|
||||
mCipherSuites[1] = 0;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
otError Dtls::SetCertificate(const uint8_t *aX509Certificate,
|
||||
uint32_t aX509CertLength,
|
||||
const uint8_t *aPrivateKey,
|
||||
uint32_t aPrivateKeyLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
assert(aX509CertLength > 0);
|
||||
assert(aX509Certificate != NULL);
|
||||
|
||||
assert(aPrivateKeyLength > 0);
|
||||
assert(aPrivateKey != NULL);
|
||||
|
||||
mOwnCertSrc = aX509Certificate;
|
||||
mOwnCertLength = aX509CertLength;
|
||||
mPrivateKeySrc = aPrivateKey;
|
||||
mPrivateKeyLength = aPrivateKeyLength;
|
||||
|
||||
mCipherSuites[0] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
|
||||
mCipherSuites[1] = 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Dtls::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
assert(aX509CaCertChainLength > 0);
|
||||
assert(aX509CaCertificateChain != NULL);
|
||||
|
||||
mCaChainSrc = aX509CaCertificateChain;
|
||||
mCaChainLength = aX509CaCertChainLength;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
otError Dtls::SetPreSharedKey(const uint8_t *aPsk,
|
||||
uint16_t aPskLength,
|
||||
const uint8_t *aPskIdentity,
|
||||
uint16_t aPskIdLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
assert(aPsk != NULL);
|
||||
assert(aPskIdentity != NULL);
|
||||
assert(aPskLength > 0);
|
||||
assert(aPskIdLength > 0);
|
||||
|
||||
mPreSharedKey = aPsk;
|
||||
mPreSharedKeyLength = aPskLength;
|
||||
mPreSharedKeyIdentity = aPskIdentity;
|
||||
mPreSharedKeyIdLength = aPskIdLength;
|
||||
|
||||
mCipherSuites[0] = MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8;
|
||||
mCipherSuites[1] = 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_BASE64_C
|
||||
|
||||
otError Dtls::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(IsConnected() == true, error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
VerifyOrExit(mbedtls_base64_encode(aPeerCert, aCertBufferSize, aCertLength, mSsl.session->peer_cert->raw.p,
|
||||
mSsl.session->peer_cert->raw.len) == 0,
|
||||
error = OT_ERROR_NO_BUFS);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif // MBEDTLS_BASE64_C
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
otError Dtls::SetClientId(const uint8_t *aClientId, uint8_t aLength)
|
||||
{
|
||||
int rval = mbedtls_ssl_set_client_transport_id(&mSsl, aClientId, aLength);
|
||||
@@ -277,7 +496,16 @@ int Dtls::HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength)
|
||||
otError error;
|
||||
int rval = 0;
|
||||
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::HandleMbedtlsTransmit");
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::HandleMbedtlsTransmit");
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
otLogInfoCoap(GetInstance(), "Dtls::ApplicationCoapSecure HandleMbedtlsTransmit");
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
error = mSendHandler(mContext, aBuf, static_cast<uint16_t>(aLength), mMessageSubType);
|
||||
|
||||
@@ -311,7 +539,16 @@ int Dtls::HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength)
|
||||
{
|
||||
int rval;
|
||||
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::HandleMbedtlsReceive");
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::HandleMbedtlsReceive");
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
otLogInfoCoap(GetInstance(), "Dtls:: ApplicationCoapSecure HandleMbedtlsReceive");
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
VerifyOrExit(mReceiveMessage != NULL && mReceiveLength != 0, rval = MBEDTLS_ERR_SSL_WANT_READ);
|
||||
|
||||
@@ -337,7 +574,16 @@ int Dtls::HandleMbedtlsGetTimer(void)
|
||||
{
|
||||
int rval;
|
||||
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::HandleMbedtlsGetTimer");
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::HandleMbedtlsGetTimer");
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
otLogInfoCoap(GetInstance(), "Dtls:: ApplicationCoapSecure HandleMbedtlsGetTimer");
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
if (!mTimerSet)
|
||||
{
|
||||
@@ -366,7 +612,16 @@ void Dtls::HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_
|
||||
|
||||
void Dtls::HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish)
|
||||
{
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::SetTimer");
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
otLogInfoMeshCoP(GetInstance(), "Dtls::SetTimer");
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
otLogInfoCoap(GetInstance(), "Dtls::ApplicationCoapSecure SetTimer");
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
if (aFinish == 0)
|
||||
{
|
||||
@@ -407,7 +662,16 @@ int Dtls::HandleMbedtlsExportKeys(const unsigned char *aMasterSecret,
|
||||
|
||||
GetNetif().GetKeyManager().SetKek(kek);
|
||||
|
||||
otLogInfoMeshCoP(GetInstance(), "Generated KEK");
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
otLogInfoMeshCoP(GetInstance(), "Generated KEK");
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
otLogInfoCoap(GetInstance(), "ApplicationCoapSecure Generated KEK");
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
OT_UNUSED_VARIABLE(aMasterSecret);
|
||||
return 0;
|
||||
@@ -420,7 +684,15 @@ void Dtls::HandleTimer(Timer &aTimer)
|
||||
|
||||
void Dtls::HandleTimer(void)
|
||||
{
|
||||
Process();
|
||||
if (!mGuardTimerSet)
|
||||
{
|
||||
Process();
|
||||
}
|
||||
else
|
||||
{
|
||||
mGuardTimerSet = false;
|
||||
mTimer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Dtls::Process(void)
|
||||
@@ -492,7 +764,10 @@ void Dtls::Process(void)
|
||||
}
|
||||
|
||||
mbedtls_ssl_session_reset(&mSsl);
|
||||
mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -511,15 +786,69 @@ otError Dtls::MapError(int rval)
|
||||
|
||||
switch (rval)
|
||||
{
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_PK_TYPE_MISMATCH:
|
||||
case MBEDTLS_ERR_PK_FILE_IO_ERROR:
|
||||
case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
|
||||
case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
|
||||
case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
|
||||
case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
|
||||
case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
|
||||
case MBEDTLS_ERR_PK_INVALID_PUBKEY:
|
||||
case MBEDTLS_ERR_PK_INVALID_ALG:
|
||||
case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
|
||||
case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_X509_SIG_MISMATCH:
|
||||
case MBEDTLS_ERR_X509_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_X509_FILE_IO_ERROR:
|
||||
case MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT:
|
||||
case MBEDTLS_ERR_X509_INVALID_VERSION:
|
||||
case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG:
|
||||
case MBEDTLS_ERR_X509_INVALID_SERIAL:
|
||||
case MBEDTLS_ERR_X509_UNKNOWN_OID:
|
||||
case MBEDTLS_ERR_X509_INVALID_FORMAT:
|
||||
case MBEDTLS_ERR_X509_INVALID_ALG:
|
||||
case MBEDTLS_ERR_X509_INVALID_NAME:
|
||||
case MBEDTLS_ERR_X509_INVALID_DATE:
|
||||
case MBEDTLS_ERR_X509_INVALID_SIGNATURE:
|
||||
case MBEDTLS_ERR_X509_INVALID_EXTENSIONS:
|
||||
case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_SSL_BAD_INPUT_DATA:
|
||||
error = OT_ERROR_INVALID_ARGS;
|
||||
break;
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_PK_ALLOC_FAILED:
|
||||
case MBEDTLS_ERR_X509_BUFFER_TOO_SMALL:
|
||||
case MBEDTLS_ERR_X509_ALLOC_FAILED:
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_SSL_ALLOC_FAILED:
|
||||
case MBEDTLS_ERR_SSL_WANT_WRITE:
|
||||
error = OT_ERROR_NO_BUFS;
|
||||
break;
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
|
||||
case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
|
||||
case MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE:
|
||||
case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
|
||||
case MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED:
|
||||
error = OT_ERROR_SECURITY;
|
||||
break;
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_X509_FATAL_ERROR:
|
||||
error = OT_ERROR_FAILED;
|
||||
break;
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
case MBEDTLS_ERR_SSL_TIMEOUT:
|
||||
error = OT_ERROR_BUSY;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(rval >= 0);
|
||||
break;
|
||||
@@ -534,25 +863,49 @@ void Dtls::HandleMbedtlsDebug(void *ctx, int level, const char *, int, const cha
|
||||
OT_UNUSED_VARIABLE(pThis);
|
||||
OT_UNUSED_VARIABLE(str);
|
||||
|
||||
switch (level)
|
||||
if (pThis->mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
case 1:
|
||||
otLogCritMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
otLogCritMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
otLogWarnMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
case 2:
|
||||
otLogWarnMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
otLogInfoMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
case 3:
|
||||
otLogInfoMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
default:
|
||||
otLogDebgMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
otLogDebgMbedTls(pThis->GetInstance(), "%s", str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
else
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
otLogCritCoap(pThis->GetInstance(), "ApplicationCoapSecure Mbedtls: %s", str);
|
||||
break;
|
||||
case 2:
|
||||
otLogWarnCoap(pThis->GetInstance(), "ApplicationCoapSecure Mbedtls: %s", str);
|
||||
break;
|
||||
case 3:
|
||||
otLogInfoCoap(pThis->GetInstance(), "ApplicationCoapSecure Mbedtls: %s", str);
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
otLogDebgCoap(pThis->GetInstance(), "ApplicationCoapSecure Mbedtls: %s", str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
|
||||
+150
-7
@@ -44,6 +44,16 @@
|
||||
#include <mbedtls/ssl.h>
|
||||
#include <mbedtls/ssl_cookie.h>
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#include <mbedtls/base64.h>
|
||||
#include <mbedtls/x509.h>
|
||||
#include <mbedtls/x509_crl.h>
|
||||
#include <mbedtls/x509_crt.h>
|
||||
#include <mbedtls/x509_csr.h>
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
#include "common/locator.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/timer.hpp"
|
||||
@@ -59,8 +69,13 @@ class Dtls : public InstanceLocator
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kPskMaxLength = 32,
|
||||
kPskMaxLength = 32,
|
||||
kGuardTimeNewConnectionMilli = 2000,
|
||||
#if !OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
kApplicationDataMaxLength = 512,
|
||||
#else
|
||||
kApplicationDataMaxLength = OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH,
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -104,11 +119,15 @@ public:
|
||||
/**
|
||||
* This method starts the DTLS service.
|
||||
*
|
||||
* @param[in] aClient TRUE if operating as a client, FALSE if operating as a server.
|
||||
* @param[in] aConnectedHandler A pointer to the connected handler.
|
||||
* @param[in] aReceiveHandler A pointer to the receive handler.
|
||||
* @param[in] aSendHandler A pointer to the send handler.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
* For CoAP Secure API do first:
|
||||
* Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or
|
||||
* set PreShared Key for use DTLS mode PSK with AES 128 CCM 8.
|
||||
*
|
||||
* @param[in] aClient TRUE if operating as a client, FALSE if operating as a server.
|
||||
* @param[in] aConnectedHandler A pointer to the connected handler.
|
||||
* @param[in] aReceiveHandler A pointer to the receive handler.
|
||||
* @param[in] aSendHandler A pointer to the send handler.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the DTLS service.
|
||||
*
|
||||
@@ -130,7 +149,7 @@ public:
|
||||
/**
|
||||
* This method indicates whether or not the DTLS service is active.
|
||||
*
|
||||
* @returns TRUE if the DTLS service is active, FALSE otherwise.
|
||||
* @returns true if the DTLS service is active, false otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsStarted(void);
|
||||
@@ -146,6 +165,94 @@ public:
|
||||
*/
|
||||
otError SetPsk(const uint8_t *aPsk, uint8_t aPskLength);
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
/**
|
||||
* This method sets the Pre-Shared Key (PSK) for DTLS sessions-
|
||||
* identified by a PSK.
|
||||
*
|
||||
* DTLS mode "PSK with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[in] aPsk A pointer to the PSK.
|
||||
* @param[in] aPskLength The PSK char length.
|
||||
* @param[in] aPskIdentity The Identity Name for the PSK.
|
||||
* @param[in] aPskIdLength The PSK Identity Length.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the PSK.
|
||||
*
|
||||
*/
|
||||
otError SetPreSharedKey(const uint8_t *aPsk,
|
||||
uint16_t aPskLength,
|
||||
const uint8_t *aPskIdentity,
|
||||
uint16_t aPskIdLength);
|
||||
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
/**
|
||||
* This method sets a reference to the own x509 certificate with corresponding private key.
|
||||
*
|
||||
* DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[in] aX509Certificate A pointer to the PEM formatted X509 certificate.
|
||||
* @param[in] aX509CertLength The length of certificate.
|
||||
* @param[in] aPrivateKey A pointer to the PEM formatted private key.
|
||||
* @param[in] aPrivateKeyLength The length of the private key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the x509 certificate with his private key.
|
||||
*
|
||||
*/
|
||||
otError SetCertificate(const uint8_t *aX509Certificate,
|
||||
uint32_t aX509CertLength,
|
||||
const uint8_t *aPrivateKey,
|
||||
uint32_t aPrivateKeyLength);
|
||||
|
||||
/**
|
||||
* This method sets the trusted top level CAs. It is needed for validate the
|
||||
* certificate of the peer.
|
||||
*
|
||||
* DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[in] aX509CaCertificateChain A pointer to the PEM formatted X509 CA chain.
|
||||
* @param[in] aX509CaCertChainLength The length of chain.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the the trusted top level CAs.
|
||||
*
|
||||
*/
|
||||
otError SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength);
|
||||
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_BASE64_C
|
||||
/**
|
||||
* This method returns the peer x509 certificate base64 encoded.
|
||||
*
|
||||
* DTLS mode "ECDHE ECDSA with AES 128 CCM 8" for Application CoAPS.
|
||||
*
|
||||
* @param[out] aPeerCert A pointer to the base64 encoded certificate buffer.
|
||||
* @param[out] aCertLength The length of the base64 encoded peer certificate.
|
||||
* @param[in] aCertBufferSize The buffer size of aPeerCert.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully get the peer certificate.
|
||||
* @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate.
|
||||
*
|
||||
*/
|
||||
otError GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize);
|
||||
#endif // MBEDTLS_BASE64_C
|
||||
|
||||
/**
|
||||
* This method set the authentication mode for a dtls connection.
|
||||
*
|
||||
* Disable or enable the verification of peer certificate.
|
||||
* Must called before start.
|
||||
*
|
||||
* @param[in] aVerifyPeerCertificate true, if the peer certificate should verify.
|
||||
*
|
||||
*/
|
||||
void SetSslAuthMode(bool aVerifyPeerCertificate);
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* This method sets the Client ID used for generating the Hello Cookie.
|
||||
*
|
||||
@@ -208,6 +315,16 @@ public:
|
||||
private:
|
||||
static otError MapError(int rval);
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Set keys and/or certificates for dtls session dependent of used cipher suite.
|
||||
*
|
||||
* @retval mbedtls error, 0 if successfully.
|
||||
*
|
||||
*/
|
||||
int SetApplicationCoapSecureKeys(void);
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
static void HandleMbedtlsDebug(void *ctx, int level, const char *file, int line, const char *str);
|
||||
|
||||
static int HandleMbedtlsGetTimer(void *aContext);
|
||||
@@ -242,9 +359,34 @@ private:
|
||||
void Close(void);
|
||||
void Process(void);
|
||||
|
||||
int mCipherSuites[2];
|
||||
uint8_t mPsk[kPskMaxLength];
|
||||
uint8_t mPskLength;
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
const uint8_t * mCaChainSrc;
|
||||
uint32_t mCaChainLength;
|
||||
const uint8_t * mOwnCertSrc;
|
||||
uint32_t mOwnCertLength;
|
||||
const uint8_t * mPrivateKeySrc;
|
||||
uint32_t mPrivateKeyLength;
|
||||
mbedtls_x509_crt mCaChain;
|
||||
mbedtls_x509_crt mOwnCert;
|
||||
mbedtls_pk_context mPrivateKey;
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
const uint8_t *mPreSharedKey;
|
||||
const uint8_t *mPreSharedKeyIdentity;
|
||||
uint16_t mPreSharedKeyLength;
|
||||
uint16_t mPreSharedKeyIdLength;
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
bool mVerifyPeerCertificate;
|
||||
|
||||
mbedtls_entropy_context mEntropy;
|
||||
mbedtls_ctr_drbg_context mCtrDrbg;
|
||||
mbedtls_ssl_context mSsl;
|
||||
@@ -265,6 +407,7 @@ private:
|
||||
SendHandler mSendHandler;
|
||||
void * mContext;
|
||||
bool mClient;
|
||||
bool mGuardTimerSet;
|
||||
|
||||
uint8_t mMessageSubType;
|
||||
uint8_t mMessageDefaultSubType;
|
||||
|
||||
@@ -1067,8 +1067,12 @@
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_HEAP_SIZE
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#define OPENTHREAD_CONFIG_HEAP_SIZE (1800 * sizeof(void *))
|
||||
#else
|
||||
#define OPENTHREAD_CONFIG_HEAP_SIZE (1536 * sizeof(void *))
|
||||
#endif
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#endif // OPENTHREAD_CONFIG_HEAP_SIZE
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_HEAP_SIZE_NO_DTLS
|
||||
@@ -1080,6 +1084,16 @@
|
||||
#define OPENTHREAD_CONFIG_HEAP_SIZE_NO_DTLS 384
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH
|
||||
*
|
||||
* The size of dtls application data when the CoAP Secure API is enabled.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH
|
||||
#define OPENTHREAD_CONFIG_DTLS_APPLICATION_DATA_MAX_LENGTH 1400
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
|
||||
*
|
||||
|
||||
Vendored
+1
@@ -62,6 +62,7 @@ libmbedcrypto_a_SOURCES = \
|
||||
repo/library/md_wrap.c \
|
||||
repo/library/memory_buffer_alloc.c \
|
||||
repo/library/oid.c \
|
||||
repo/library/pem.c \
|
||||
repo/library/pk.c \
|
||||
repo/library/pk_wrap.c \
|
||||
repo/library/pkparse.c \
|
||||
|
||||
Vendored
+104
@@ -527,6 +527,15 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
*/
|
||||
//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Enable the PSK ciphersuite for Application Coap Secure.
|
||||
*/
|
||||
#ifndef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
|
||||
*
|
||||
@@ -699,6 +708,29 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
*/
|
||||
//#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Enables ciphersuite ECDHE ECDSA with x.509 certificate
|
||||
* for Application Coap Secure.
|
||||
*/
|
||||
#ifndef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
|
||||
/**
|
||||
* To increase the security with ECDHE ECDSA enable
|
||||
* X509 CHECK KEY USAGE.
|
||||
* Not required!
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_X509_CHECK_KEY_USAGE
|
||||
//#define MBEDTLS_X509_CHECK_KEY_USAGE
|
||||
#endif // MBEDTLS_X509_CHECK_KEY_USAGE
|
||||
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
|
||||
*
|
||||
@@ -1569,6 +1601,18 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
*/
|
||||
//#define MBEDTLS_BASE64_C
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Requiered by ciphersuite ECDHE ECDSA with x.509 certificate
|
||||
* used by Application CoAP Secure.
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#ifndef MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_BASE64_C
|
||||
#endif // MBEDTLS_BASE64_C
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_BIGNUM_C
|
||||
*
|
||||
@@ -1786,6 +1830,17 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
#define MBEDTLS_ECDH_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
/**
|
||||
* Required for ECDHE_ECDSA by Application CoAPS.
|
||||
*/
|
||||
#ifndef MBEDTLS_ECDH_C
|
||||
#define MBEDTLS_ECDH_C
|
||||
#endif // MBEDTLS_ECDH_C
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ECDSA_C
|
||||
*
|
||||
@@ -1803,6 +1858,17 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Required for ECDHA ECDSA by Application CoAPS.
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#ifndef MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#endif // MBEDTLS_ECDSA_C
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ECJPAKE_C
|
||||
*
|
||||
@@ -2056,6 +2122,18 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
*/
|
||||
//#define MBEDTLS_PEM_PARSE_C
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Requiered by ciphersuite ECDHE ECDSA with x.509 certificate
|
||||
* used by Application CoAP Secure.
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#ifndef MBEDTLS_PEM_PARSE_C
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
#endif // MBEDTLS_PEM_PARSE_C
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PEM_WRITE_C
|
||||
*
|
||||
@@ -2411,6 +2489,17 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
#define MBEDTLS_X509_USE_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Required for ECDHE ECDSA by Application CoAPS.
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#ifndef MBEDTLS_X509_USE_C
|
||||
#define MBEDTLS_X509_USE_C
|
||||
#endif // MBEDTLS_X509_USE_C
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_X509_CRT_PARSE_C
|
||||
*
|
||||
@@ -2429,6 +2518,17 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
/**
|
||||
* Required for ECDHE ECDSA by Application CoAPS.
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
|
||||
#ifndef MBEDTLS_X509_CRT_PARSE_C
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
#endif // MBEDTLS_X509_CRT_PARSE_C
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_X509_CRL_PARSE_C
|
||||
*
|
||||
@@ -2591,7 +2691,11 @@ __inline int windows_kernel_snprintf(char * s, size_t n, const char * format, ..
|
||||
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
|
||||
|
||||
/* SSL options */
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
|
||||
#else
|
||||
#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
|
||||
#endif
|
||||
//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
|
||||
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
|
||||
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
|
||||
|
||||
Reference in New Issue
Block a user