mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 22:57:47 +00:00
[joiner] add validation of joiner PSKd (#4934)
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
#include "common/logging.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "crypto/pbkdf2_cmac.h"
|
||||
#include "meshcop/joiner.hpp"
|
||||
#include "meshcop/joiner_router.hpp"
|
||||
#include "meshcop/meshcop.hpp"
|
||||
#include "meshcop/meshcop_tlvs.hpp"
|
||||
@@ -285,7 +286,7 @@ otError Commissioner::AddJoiner(const Mac::ExtAddress *aEui64, const char *aPskd
|
||||
|
||||
VerifyOrExit(mState == OT_COMMISSIONER_STATE_ACTIVE, error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
VerifyOrExit(StringLength(aPskd, Dtls::kPskMaxLength + 1) <= Dtls::kPskMaxLength, error = OT_ERROR_INVALID_ARGS);
|
||||
VerifyOrExit(MeshCoP::Joiner::IsPskdValid(aPskd), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
IgnoreError(RemoveJoiner(aEui64, 0, kJoinerOpFlagNotNotifyLeader)); // remove immediately
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "meshcop/meshcop.hpp"
|
||||
#include "radio/radio.hpp"
|
||||
#include "thread/thread_netif.hpp"
|
||||
@@ -86,6 +87,30 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
bool Joiner::IsPskdValid(const char *aPskd)
|
||||
{
|
||||
bool valid = false;
|
||||
size_t pskdLength = StringLength(aPskd, kPskdMaxLength + 1);
|
||||
|
||||
OT_STATIC_ASSERT(static_cast<uint8_t>(kPskdMaxLength) <= static_cast<uint8_t>(Dtls::kPskMaxLength),
|
||||
"The maximum length of DTLS PSK is smaller than joiner PSKd");
|
||||
|
||||
VerifyOrExit(pskdLength >= kPskdMinLength && pskdLength <= kPskdMaxLength, OT_NOOP);
|
||||
|
||||
for (size_t i = 0; i < pskdLength; i++)
|
||||
{
|
||||
char c = aPskd[i];
|
||||
|
||||
VerifyOrExit(isdigit(c) || isupper(c), OT_NOOP);
|
||||
VerifyOrExit(c != 'I' && c != 'O' && c != 'Q' && c != 'Z', OT_NOOP);
|
||||
}
|
||||
|
||||
valid = true;
|
||||
|
||||
exit:
|
||||
return valid;
|
||||
}
|
||||
|
||||
otError Joiner::Start(const char * aPskd,
|
||||
const char * aProvisioningUrl,
|
||||
const char * aVendorName,
|
||||
@@ -102,6 +127,8 @@ otError Joiner::Start(const char * aPskd,
|
||||
|
||||
VerifyOrExit(mState == OT_JOINER_STATE_IDLE, error = OT_ERROR_BUSY);
|
||||
|
||||
VerifyOrExit(IsPskdValid(aPskd), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
// Use random-generated extended address.
|
||||
randomAddress.GenerateRandom();
|
||||
Get<Mac::Mac>().SetExtAddress(randomAddress);
|
||||
|
||||
@@ -109,12 +109,29 @@ public:
|
||||
*/
|
||||
void GetJoinerId(Mac::ExtAddress &aJoinerId) const;
|
||||
|
||||
/**
|
||||
* This method validates the PSKd.
|
||||
*
|
||||
* Per Thread specification, a Joining Device Credential is encoded as
|
||||
* uppercase alphanumeric characters (base32-thread: 0-9, A-Z excluding
|
||||
* I, O, Q, and Z for readability) with a minimum length of 6 such
|
||||
* characters and a maximum length of 32 such characters.
|
||||
*
|
||||
* param[in] aPskd The PSKd to validate.
|
||||
*
|
||||
* @retval A boolean indicates whether the given @p aPskd is valid.
|
||||
*
|
||||
*/
|
||||
static bool IsPskdValid(const char *aPskd);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kJoinerUdpPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT,
|
||||
kConfigExtAddressDelay = 100, ///< [milliseconds]
|
||||
kReponseTimeout = 4000, ///< Maximum wait time to receive response [milliseconds].
|
||||
kPskdMinLength = 6, ///< Minimum PSKd length.
|
||||
kPskdMaxLength = 32, ///< Maximum PSKd Length.
|
||||
};
|
||||
|
||||
struct JoinerRouter
|
||||
|
||||
@@ -62,10 +62,10 @@ class Cert_8_1_01_Commissioning(thread_cert.TestCase):
|
||||
self.nodes[COMMISSIONER].commissioner_start()
|
||||
self.simulator.go(3)
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(
|
||||
self.nodes[JOINER].get_eui64(), 'OPENTHREAD')
|
||||
self.nodes[JOINER].get_eui64(), 'PSKD01')
|
||||
|
||||
self.nodes[JOINER].interface_up()
|
||||
self.nodes[JOINER].joiner_start('OPENTHREAD')
|
||||
self.nodes[JOINER].joiner_start('PSKD01')
|
||||
self.simulator.go(10)
|
||||
self.simulator.read_cert_messages_in_commissioning_log(
|
||||
[COMMISSIONER, JOINER])
|
||||
|
||||
@@ -57,10 +57,10 @@ class Cert_8_1_02_Commissioning(thread_cert.TestCase):
|
||||
self.nodes[COMMISSIONER].commissioner_start()
|
||||
self.simulator.go(3)
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(
|
||||
self.nodes[JOINER].get_eui64(), 'OPENTHREAD')
|
||||
self.nodes[JOINER].get_eui64(), 'PSKD01')
|
||||
|
||||
self.nodes[JOINER].interface_up()
|
||||
self.nodes[JOINER].joiner_start('DAERHTNEPO')
|
||||
self.nodes[JOINER].joiner_start('10DKSP')
|
||||
self.simulator.go(10)
|
||||
self.assertNotEqual(
|
||||
self.nodes[JOINER].get_masterkey(),
|
||||
|
||||
@@ -65,9 +65,9 @@ class Cert_8_2_01_JoinerRouter(thread_cert.TestCase):
|
||||
self.nodes[COMMISSIONER].commissioner_start()
|
||||
self.simulator.go(5)
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(
|
||||
self.nodes[JOINER_ROUTER].get_eui64(), 'OPENTHREAD')
|
||||
self.nodes[JOINER_ROUTER].get_eui64(), 'PSKD01')
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(
|
||||
self.nodes[JOINER].get_eui64(), 'OPENTHREAD2')
|
||||
self.nodes[JOINER].get_eui64(), 'PSKD02')
|
||||
self.simulator.go(5)
|
||||
|
||||
self.nodes[COMMISSIONER].add_whitelist(
|
||||
@@ -76,7 +76,7 @@ class Cert_8_2_01_JoinerRouter(thread_cert.TestCase):
|
||||
self.nodes[COMMISSIONER].get_addr64())
|
||||
|
||||
self.nodes[JOINER_ROUTER].interface_up()
|
||||
self.nodes[JOINER_ROUTER].joiner_start('OPENTHREAD')
|
||||
self.nodes[JOINER_ROUTER].joiner_start('PSKD01')
|
||||
self.simulator.go(10)
|
||||
self.assertEqual(
|
||||
self.nodes[JOINER_ROUTER].get_masterkey(),
|
||||
@@ -95,7 +95,7 @@ class Cert_8_2_01_JoinerRouter(thread_cert.TestCase):
|
||||
self.nodes[JOINER].add_whitelist(self.nodes[JOINER_ROUTER].get_addr64())
|
||||
|
||||
self.nodes[JOINER].interface_up()
|
||||
self.nodes[JOINER].joiner_start('OPENTHREAD2')
|
||||
self.nodes[JOINER].joiner_start('PSKD02')
|
||||
self.simulator.go(10)
|
||||
self.assertEqual(
|
||||
self.nodes[JOINER].get_masterkey(),
|
||||
|
||||
@@ -65,9 +65,9 @@ class Cert_8_2_02_JoinerRouter(thread_cert.TestCase):
|
||||
self.nodes[COMMISSIONER].commissioner_start()
|
||||
self.simulator.go(5)
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(
|
||||
self.nodes[JOINER_ROUTER].get_eui64(), 'OPENTHREAD')
|
||||
self.nodes[JOINER_ROUTER].get_eui64(), 'PSKD01')
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(
|
||||
self.nodes[JOINER].get_eui64(), 'OPENTHREAD2')
|
||||
self.nodes[JOINER].get_eui64(), 'PSKD02')
|
||||
self.simulator.go(5)
|
||||
|
||||
self.nodes[COMMISSIONER].add_whitelist(
|
||||
@@ -76,7 +76,7 @@ class Cert_8_2_02_JoinerRouter(thread_cert.TestCase):
|
||||
self.nodes[COMMISSIONER].get_addr64())
|
||||
|
||||
self.nodes[JOINER_ROUTER].interface_up()
|
||||
self.nodes[JOINER_ROUTER].joiner_start('OPENTHREAD')
|
||||
self.nodes[JOINER_ROUTER].joiner_start('PSKD01')
|
||||
self.simulator.go(10)
|
||||
self.assertEqual(
|
||||
self.nodes[JOINER_ROUTER].get_masterkey(),
|
||||
@@ -95,7 +95,7 @@ class Cert_8_2_02_JoinerRouter(thread_cert.TestCase):
|
||||
self.nodes[JOINER].add_whitelist(self.nodes[JOINER_ROUTER].get_addr64())
|
||||
|
||||
self.nodes[JOINER].interface_up()
|
||||
self.nodes[JOINER].joiner_start('2DAERHTNEPO')
|
||||
self.nodes[JOINER].joiner_start('20DKSP')
|
||||
self.simulator.go(10)
|
||||
self.assertNotEqual(
|
||||
self.nodes[JOINER].get_masterkey(),
|
||||
|
||||
@@ -2035,7 +2035,7 @@ class OpenThread(IThci):
|
||||
def diagnosticQuery(self, strDestinationAddr, listTLV_ids=[]):
|
||||
self.diagnosticGet(strDestinationAddr, listTLV_ids)
|
||||
|
||||
def startNativeCommissioner(self, strPSKc='GRLpassWord'):
|
||||
def startNativeCommissioner(self, strPSKc='GRLPASSPHRASE'):
|
||||
# TODO: Support the whole Native Commissioner functionality
|
||||
# Currently it only aims to trigger a Discovery Request message to pass
|
||||
# Certification test 5.8.4
|
||||
@@ -2069,7 +2069,7 @@ class OpenThread(IThci):
|
||||
def setJoinKey(self, strPSKc):
|
||||
pass
|
||||
|
||||
def scanJoiner(self, xEUI='*', strPSKd='threadjpaketest'):
|
||||
def scanJoiner(self, xEUI='*', strPSKd='THREADJPAKETEST'):
|
||||
"""scan Joiner
|
||||
|
||||
Args:
|
||||
@@ -2143,7 +2143,7 @@ class OpenThread(IThci):
|
||||
ModuleHelper.writeintodebuglogger('allowcommission() error: ' +
|
||||
str(e))
|
||||
|
||||
def joinCommissioned(self, strPSKd='threadjpaketest', waitTime=20):
|
||||
def joinCommissioned(self, strPSKd='THREADJPAKETEST', waitTime=20):
|
||||
"""start joiner
|
||||
|
||||
Args:
|
||||
|
||||
@@ -2117,7 +2117,7 @@ class OpenThread_WpanCtl(IThci):
|
||||
def diagnosticReset(self, strDestinationAddr, listTLV_ids=[]):
|
||||
"""@todo : required if as reference device"""
|
||||
|
||||
def startNativeCommissioner(self, strPSKc='GRLpassWord'):
|
||||
def startNativeCommissioner(self, strPSKc='GRLPASSPHRASE'):
|
||||
# TODO: Support the whole Native Commissioner functionality
|
||||
# Currently it only aims to trigger a Discovery Request message to pass
|
||||
# Certification test 5.8.4
|
||||
@@ -2152,7 +2152,7 @@ class OpenThread_WpanCtl(IThci):
|
||||
def setJoinKey(self, strPSKc):
|
||||
pass
|
||||
|
||||
def scanJoiner(self, xEUI='*', strPSKd='threadjpaketest'):
|
||||
def scanJoiner(self, xEUI='*', strPSKd='THREADJPAKETEST'):
|
||||
"""scan Joiner
|
||||
|
||||
Args:
|
||||
@@ -2225,7 +2225,7 @@ class OpenThread_WpanCtl(IThci):
|
||||
ModuleHelper.WriteIntoDebugLogger('allowcommission() error: ' +
|
||||
str(e))
|
||||
|
||||
def joinCommissioned(self, strPSKd='threadjpaketest', waitTime=20):
|
||||
def joinCommissioned(self, strPSKd='THREADJPAKETEST', waitTime=20):
|
||||
"""start joiner
|
||||
|
||||
Args:
|
||||
|
||||
Reference in New Issue
Block a user