From 30f1f01c1ff567ecf7c24142a1ec8eff9bd7031c Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 29 Oct 2021 05:34:55 +0200 Subject: Move SMPKeyBin 'apply' to BTDevice, splitting functionality: setting + uploading keys (required for peripheral BTAdapter key management) SMPKeyBin has the key apply action revoked. SMPKeyBin is reduced to store keys, address and security settings, as well adding persistence (read/write to filesystem). BTDevice::setSMPKeyBin(SMPKeyBin&) shall be used copy the key data over and BTDevice::uploadKeys() to upload them to the adapter for pre-pairing. See dbt_scanner10.cpp's use of convenient API (same efficiency as before) device->uploadKeys(KEY_PATH, req_sec_level, true /* verbose_ */); BTDevice::setSMPKeyBin(SMPKeyBin&) fully restored BTDevice's PairingData - keys - key caps - user security level and IOCaps +++ The reduced 'setKey(..)' methods only - copy the key to BTDevice's PairingData - set the KeyType bit for keys__[init|resp], fully restoring key caps --- api/direct_bt/BTDevice.hpp | 137 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 112 insertions(+), 25 deletions(-) (limited to 'api/direct_bt/BTDevice.hpp') diff --git a/api/direct_bt/BTDevice.hpp b/api/direct_bt/BTDevice.hpp index 40294463..774b28ef 100644 --- a/api/direct_bt/BTDevice.hpp +++ b/api/direct_bt/BTDevice.hpp @@ -43,6 +43,7 @@ #include "MgmtTypes.hpp" #include "SMPHandler.hpp" #include "BTGattHandler.hpp" +#include "SMPKeyBin.hpp" namespace direct_bt { @@ -601,6 +602,83 @@ namespace direct_bt { */ SMPKeyType getAvailableSMPKeys(const bool responder) const noexcept; + /** + * Copy all keys from the given SMPKeyBin into this BTDevice. + * + * Issue uploadKeys() to upload all SMP keys to the adapter + * before connecting to enable pre-pairing. + * + * If SMPKeyBin::isValid() and initiator or responder LTK available, + * the following procedure will be applied to this BTDevice: + * + * - If BTSecurityLevel _is_ BTSecurityLevel::NONE + * + Setting security to ::BTSecurityLevel::NONE and ::SMPIOCapability::NO_INPUT_NO_OUTPUT via BTDevice::setConnSecurity() + * - else if BTSecurityLevel > BTSecurityLevel::NONE + * + Setting security to ::BTSecurityLevel::ENC_ONLY and ::SMPIOCapability::NO_INPUT_NO_OUTPUT via BTDevice::setConnSecurity() + * - Copying all keys from SMPKeyBin to this device, without uploading to the adapter + * + * ::BTSecurityLevel::ENC_ONLY is set to avoid a new SMP ::PairingMode negotiation, + * which is undesired as this instances' stored LTK shall be used for ::PairingMode::PRE_PAIRED. + * + * @param bin + * @return true if successful, false if pairing is currently in progress + * @see setLongTermKey() + * @see setIdentityResolvingKey() + * @see setSignatureResolvingKey() + * @see setLinkKey() + * @see uploadKeys() + * @since 2.4.0 + */ + bool setSMPKeyBin(const SMPKeyBin& bin) noexcept; + + /** + * Upload all set keys to the adapter for pre-pairing. + * + * Must be called before connecting to this device, otherwise HCIStatusCode::CONNECTION_ALREADY_EXISTS will be returned. + * + * @return ::HCIStatusCode::SUCCESS if successful, otherwise the appropriate error code. + * @see setLongTermKey() + * @see setIdentityResolvingKey() + * @see setSignatureResolvingKey() + * @see setLinkKey() + * @see setSMPKeyBin() + * @since 2.4.0 + */ + HCIStatusCode uploadKeys() noexcept; + + /** + * Convenient combination of setSMPKeyBin() and uploadKeys() + * after validating given SMPKeyBin file and SMPKeyBin::getSecLevel() > req_min_level. + * @param bin the SMPKeyBin file + * @param req_min_level SMPKeyBin::getSecLevel() shall be greater or equal to this required minimum + * @return ::HCIStatusCode::SUCCESS if successful, otherwise the appropriate error code. + * @see setSMPKeyBin() + * @see uploadKeys() + * @since 2.4.0 + */ + HCIStatusCode uploadKeys(const SMPKeyBin& bin, const BTSecurityLevel req_min_level) noexcept { + if( bin.isValid() && bin.getSecLevel() >= req_min_level && setSMPKeyBin(bin) ) { + return uploadKeys(); + } else { + return HCIStatusCode::INVALID_PARAMS; + } + } + + /** + * Convenient combination of SMPKeyBin::read(), setSMPKeyBin() and uploadKeys() + * after validating given SMPKeyBin file and SMPKeyBin::getSecLevel() > req_min_level. + * @param smp_key_bin_path director for the SMPKeyBin file, derived by this BTDevice + * @param req_min_level SMPKeyBin::getSecLevel() shall be greater or equal to this required minimum + * @return ::HCIStatusCode::SUCCESS if successful, otherwise the appropriate error code. + * @see SMPKeyBin::read() + * @see setSMPKeyBin() + * @see uploadKeys() + * @since 2.4.0 + */ + HCIStatusCode uploadKeys(const std::string& smp_key_bin_path, const BTSecurityLevel req_min_level, const bool verbose_) noexcept { + return uploadKeys(SMPKeyBin::read(smp_key_bin_path, *this, verbose_), req_min_level); + } + /** * Returns a copy of the Long Term Key (LTK), valid after connection and SMP pairing has been completed. * @param responder true will return the responder's LTK info (remote device, LL slave), otherwise the initiator's (the LL master). @@ -611,14 +689,17 @@ namespace direct_bt { SMPLongTermKey getLongTermKey(const bool responder) const noexcept; /** - * Sets the Long Term Key (LTK) of this device to reuse for pre-paired encryption. - *

- * Must be called before connecting to this device, otherwise HCIStatusCode::CONNECTION_ALREADY_EXISTS will be returned. - *

+ * Sets the Long Term Key (LTK) of this device for pre-paired encryption. + * + * Issue uploadKeys() to upload all SMP keys to the adapter + * before connecting to enable pre-pairing. + * * @param ltk the pre-paired encryption LTK - * @return ::HCIStatusCode::SUCCESS if successful, otherwise the appropriate error code. + * @see setSMPKeyBin() + * @see uploadKeys() + * @since 2.4.0 */ - HCIStatusCode setLongTermKey(const SMPLongTermKey& ltk) noexcept; + void setLongTermKey(const SMPLongTermKey& ltk) noexcept; /** * Returns a copy of the Identity Resolving Key (IRK), valid after connection and SMP pairing has been completed. @@ -630,15 +711,17 @@ namespace direct_bt { SMPIdentityResolvingKey getIdentityResolvingKey(const bool responder) const noexcept; /** - * Sets the Identity Resolving Key (IRK) of this device to be reused. - *

- * Must be called before connecting to this device, otherwise HCIStatusCode::CONNECTION_ALREADY_EXISTS will be returned. - *

+ * Sets the Identity Resolving Key (IRK) of this device for pre-paired encryption. + * + * Issue uploadKeys() to upload all SMP keys to the adapter + * before connecting to enable pre-pairing. + * * @param irk the Identity Resolving Key (IRK) - * @return ::HCIStatusCode::SUCCESS if successful, otherwise the appropriate error code. + * @see setSMPKeyBin() + * @see uploadKeys() * @since 2.4.0 */ - HCIStatusCode setIdentityResolvingKey(const SMPIdentityResolvingKey& irk) noexcept; + void setIdentityResolvingKey(const SMPIdentityResolvingKey& irk) noexcept; /** * Returns a copy of the Signature Resolving Key (CSRK), valid after connection and SMP pairing has been completed. @@ -650,15 +733,17 @@ namespace direct_bt { SMPSignatureResolvingKey getSignatureResolvingKey(const bool responder) const noexcept; /** - * Sets the Signature Resolving Key (CSRK) of this device to be reused. - *

- * Must be called before connecting to this device, otherwise HCIStatusCode::CONNECTION_ALREADY_EXISTS will be returned. - *

+ * Sets the Signature Resolving Key (CSRK) of this device for pre-paired encryption. + * + * Issue uploadKeys() to upload all SMP keys to the adapter + * before connecting to enable pre-pairing. + * * @param csrk the Signature Resolving Key (CSRK) - * @return ::HCIStatusCode::SUCCESS if successful, otherwise the appropriate error code. + * @see setSMPKeyBin() + * @see uploadKeys() * @since 2.4.0 */ - HCIStatusCode setSignatureResolvingKey(const SMPSignatureResolvingKey& csrk) noexcept; + void setSignatureResolvingKey(const SMPSignatureResolvingKey& csrk) noexcept; /** * Returns a copy of the Link Key (LK), valid after connection and SMP pairing has been completed. @@ -671,18 +756,20 @@ namespace direct_bt { SMPLinkKey getLinkKey(const bool responder) const noexcept; /** - * Sets the Link Key (LK) of this device to reuse for pre-paired encryption. - *

- * Must be called before connecting to this device, otherwise HCIStatusCode::CONNECTION_ALREADY_EXISTS will be returned. - *

+ * Sets the Link Key (LK) of this device for pre-paired encryption. + * + * Issue uploadKeys() to upload all SMP keys to the adapter + * before connecting to enable pre-pairing. + * * @param lk the pre-paired encryption LK - * @return ::HCIStatusCode::SUCCESS if successful, otherwise the appropriate error code. + * @see setSMPKeyBin() + * @see uploadKeys() * @since 2.4.0 */ - HCIStatusCode setLinkKey(const SMPLinkKey& lk) noexcept; + void setLinkKey(const SMPLinkKey& lk) noexcept; /** - * Unpairs this device from the adapter while staying connected. + * Unpair this device from the adapter while staying connected. *

* All keys will be cleared within the adapter and host implementation.
* Should rarely being used by user.
-- cgit v1.2.3