blob: 98d015640e3401267521f229da75538de0cee270 [file] [log] [blame]
/*
* Copyright (c) 2023, 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 BLE Secure implementation.
*
* @note
* The functions in this module require the build-time feature `OPENTHREAD_CONFIG_BLE_TCAT_ENABLE=1`.
*
* @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_BLE_SECURE_H_
#define OPENTHREAD_BLE_SECURE_H_
#include <stdint.h>
#include <openthread/message.h>
#include <openthread/tcat.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup api-ble-secure
*
* @brief
* This module includes functions that control BLE Secure (TLS over BLE) communication.
*
* The functions in this module are available when BLE Secure API feature
* (`OPENTHREAD_CONFIG_BLE_TCAT_ENABLE`) is enabled.
*
* @{
*
*/
/**
* Pointer to call when ble secure connection state changes.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aConnected TRUE, if a secure connection was established, FALSE otherwise.
* @param[in] aBleConnectionOpen TRUE if a BLE connection was established to carry a TLS data stream, FALSE
* otherwise.
* @param[in] aContext A pointer to arbitrary context information.
*
*/
typedef void (*otHandleBleSecureConnect)(otInstance *aInstance,
bool aConnected,
bool aBleConnectionOpen,
void *aContext);
/**
* Pointer to call when data was received over a BLE Secure TLS connection.
*
*/
typedef otHandleTcatApplicationDataReceive otHandleBleSecureReceive;
/**
* Starts the BLE Secure service.
* When TLV mode is active, the function @p aReceiveHandler will be called once a complete TLV was received and the
* message offset points to the TLV value.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aConnectHandler A pointer to a function that will be called when the connection
* state changes.
* @param[in] aReceiveHandler A pointer to a function that will be called once data has been received
* over the TLS connection.
* @param[in] aTlvMode A boolean value indicating if line mode shall be activated.
* @param[in] aContext A pointer to arbitrary context information. May be NULL if not used.
*
* @retval OT_ERROR_NONE Successfully started the BLE Secure server.
* @retval OT_ERROR_ALREADY The service was stated already.
*
*/
otError otBleSecureStart(otInstance *aInstance,
otHandleBleSecureConnect aConnectHandler,
otHandleBleSecureReceive aReceiveHandler,
bool aTlvMode,
void *aContext);
/**
* Enables the TCAT protocol over BLE Secure.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aVendorInfo A pointer to the Vendor Information (must remain valid after the method call, may be
* NULL).
* @param[in] aHandler A pointer to a function that is called when the join operation completes.
*
* @retval OT_ERROR_NONE Successfully started the BLE Secure Joiner role.
* @retval OT_ERROR_INVALID_ARGS @p aElevationPsk or @p aVendorInfo is invalid.
* @retval OT_ERROR_INVALID_STATE The BLE function has not been started or line mode is not selected.
*
*/
otError otBleSecureTcatStart(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo, otHandleTcatJoin aHandler);
/**
* Stops the BLE Secure server.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
*/
void otBleSecureStop(otInstance *aInstance);
/**
* Sets the Pre-Shared Key (PSK) and cipher suite
* TLS_PSK_WITH_AES_128_CCM_8.
*
* @note Requires the build-time feature `MBEDTLS_KEY_EXCHANGE_PSK_ENABLED` to be enabled.
*
* @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.
*
*/
void otBleSecureSetPsk(otInstance *aInstance,
const uint8_t *aPsk,
uint16_t aPskLength,
const uint8_t *aPskIdentity,
uint16_t aPskIdLength);
/**
* Returns the peer x509 certificate base64 encoded.
*
* @note Requires the build-time features `MBEDTLS_BASE64_C` and
* `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[out] aPeerCert A pointer to the base64 encoded certificate buffer.
* @param[in,out] aCertLength On input, the size the max size of @p aPeerCert.
* On output, the length of the base64 encoded peer certificate.
*
* @retval OT_ERROR_NONE Successfully get the peer certificate.
* @retval OT_ERROR_INVALID_ARGS @p aInstance or @p aCertLength is invalid.
* @retval OT_ERROR_INVALID_STATE Not connected yet.
* @retval OT_ERROR_NO_BUFS Can't allocate memory for certificate.
*
*/
otError otBleSecureGetPeerCertificateBase64(otInstance *aInstance, unsigned char *aPeerCert, size_t *aCertLength);
/**
* Returns an attribute value identified by its OID from the subject
* of the peer x509 certificate. The peer OID is provided in binary format.
* The attribute length is set if the attribute was successfully read or zero
* if unsuccessful. The ASN.1 type as is set as defineded in the ITU-T X.690 standard
* if the attribute was successfully read.
*
* @note Requires the build-time feature
* `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aOid A pointer to the OID to be found.
* @param[in] aOidLength The length of the OID.
* @param[out] aAttributeBuffer A pointer to the attribute buffer.
* @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer.
* On output, the length of the attribute written to the buffer.
* @param[out] aAsn1Type A pointer to the ASN.1 type of the attribute written to the buffer.
*
* @retval OT_ERROR_INVALID_STATE Not connected yet.
* @retval OT_ERROR_INVALID_ARGS Invalid attribute length.
* @retval OT_ERROR_NONE Successfully read attribute.
* @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value.
*
*/
otError otBleSecureGetPeerSubjectAttributeByOid(otInstance *aInstance,
const char *aOid,
size_t aOidLength,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength,
int *aAsn1Type);
/**
* Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of
* the peer x509 certificate, where the last digit x is set to aThreadOidDescriptor.
* The attribute length is set if the attribute was successfully read or zero if unsuccessful.
* Requires a connection to be active.
*
* @note Requires the build-time feature
* `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` to be enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID.
* @param[out] aAttributeBuffer A pointer to the attribute buffer.
* @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer.
* On output, the length of the attribute written to the buffer.
*
* @retval OT_ERROR_NONE Successfully read attribute.
* @retval OT_ERROR_INVALID_ARGS Invalid attribute length.
* @retval OT_NOT_FOUND The requested attribute was not found.
* @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value.
* @retval OT_ERROR_INVALID_STATE Not connected yet.
* @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127.
* @retval OT_ERROR_PARSE The certificate extensions could not be parsed.
*
*/
otError otBleSecureGetThreadAttributeFromPeerCertificate(otInstance *aInstance,
int aThreadOidDescriptor,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength);
/**
* Returns an attribute value for the OID 1.3.6.1.4.1.44970.x from the v3 extensions of
* the own x509 certificate, where the last digit x is set to aThreadOidDescriptor.
* The attribute length is set if the attribute was successfully read or zero if unsuccessful.
* Requires a connection to be active.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aThreadOidDescriptor The last digit of the Thread attribute OID.
* @param[out] aAttributeBuffer A pointer to the attribute buffer.
* @param[in,out] aAttributeLength On input, the size the max size of @p aAttributeBuffer.
* On output, the length of the attribute written to the buffer.
*
* @retval OT_ERROR_NONE Successfully read attribute.
* @retval OT_ERROR_INVALID_ARGS Invalid attribute length.
* @retval OT_NOT_FOUND The requested attribute was not found.
* @retval OT_ERROR_NO_BUFS Insufficient memory for storing the attribute value.
* @retval OT_ERROR_INVALID_STATE Not connected yet.
* @retval OT_ERROR_NOT_IMPLEMENTED The value of aThreadOidDescriptor is >127.
* @retval OT_ERROR_PARSE The certificate extensions could not be parsed.
*
*/
otError otBleSecureGetThreadAttributeFromOwnCertificate(otInstance *aInstance,
int aThreadOidDescriptor,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength);
/**
* Sets the authentication mode for the BLE 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 otBleSecureSetSslAuthMode(otInstance *aInstance, bool aVerifyPeerCertificate);
/**
* Sets the local device's X509 certificate with corresponding private key for
* TLS session with TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8.
*
* @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aX509Cert 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.
*
*/
void otBleSecureSetCertificate(otInstance *aInstance,
const uint8_t *aX509Cert,
uint32_t aX509Length,
const uint8_t *aPrivateKey,
uint32_t aPrivateKeyLength);
/**
* Sets the trusted top level CAs. It is needed for validating the
* certificate of the peer.
*
* TLS mode "ECDHE ECDSA with AES 128 CCM 8" for secure BLE.
*
* @note Requires `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=1`.
*
* @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.
*
*/
void otBleSecureSetCaCertificateChain(otInstance *aInstance,
const uint8_t *aX509CaCertificateChain,
uint32_t aX509CaCertChainLength);
/**
* Initializes TLS session with a peer using an already open BLE connection.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval OT_ERROR_NONE Successfully started TLS connection.
*
*/
otError otBleSecureConnect(otInstance *aInstance);
/**
* Stops the BLE and TLS connection.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
*/
void otBleSecureDisconnect(otInstance *aInstance);
/**
* Indicates whether or not the TLS session is active (connected or conneting).
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval TRUE If TLS session is active.
* @retval FALSE If TLS session is not active.
*
*/
bool otBleSecureIsConnectionActive(otInstance *aInstance);
/**
* Indicates whether or not the TLS session is connected.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval TRUE The TLS session is connected.
* @retval FALSE The TLS session is not connected.
*
*/
bool otBleSecureIsConnected(otInstance *aInstance);
/**
* Indicates whether or not the TCAT agent is enabled.
*
* @retval TRUE The TCAT agent is enabled.
* @retval FALSE The TCAT agent is not enabled.
*
*/
bool otBleSecureIsTcatEnabled(otInstance *aInstance);
/**
* Indicates whether or not a TCAT command class is authorized.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aCommandClass A command class to check.
*
* @retval TRUE The command class is authorized.
* @retval FALSE The command class is not authorized.
*
*/
bool otBleSecureIsCommandClassAuthorized(otInstance *aInstance, otTcatCommandClass aCommandClass);
/**
* Sends a secure BLE message.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aMessage A pointer to the message to send.
*
* If the return value is OT_ERROR_NONE, OpenThread takes ownership of @p aMessage, and the caller should no longer
* reference @p aMessage. If the return value is not OT_ERROR_NONE, the caller retains ownership of @p aMessage,
* including freeing @p aMessage if the message buffer is no longer needed.
*
* @retval OT_ERROR_NONE Successfully sent message.
* @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory.
* @retval OT_ERROR_INVALID_STATE TLS connection was not initialized.
*
*/
otError otBleSecureSendMessage(otInstance *aInstance, otMessage *aMessage);
/**
* Sends a secure BLE data packet.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV.
* @param[in] aLength A number indicating the length of the data buffer.
*
* @retval OT_ERROR_NONE Successfully sent data.
* @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory.
* @retval OT_ERROR_INVALID_STATE TLS connection was not initialized.
*
*/
otError otBleSecureSend(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength);
/**
* Sends a secure BLE data packet containing a TCAT Send Application Data TLV.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aBuf A pointer to the data to send as the Value of the TCAT Send Application Data TLV.
* @param[in] aLength A number indicating the length of the data buffer.
*
* @retval OT_ERROR_NONE Successfully sent data.
* @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory.
* @retval OT_ERROR_INVALID_STATE TLS connection was not initialized.
*
*/
otError otBleSecureSendApplicationTlv(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength);
/**
* Flushes the send buffer.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval OT_ERROR_NONE Successfully flushed output buffer.
* @retval OT_ERROR_NO_BUFS Failed to allocate buffer memory.
* @retval OT_ERROR_INVALID_STATE TLS connection was not initialized.
*
*/
otError otBleSecureFlush(otInstance *aInstance);
/**
* @}
*
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* OPENTHREAD_BLE_SECURE_H_ */