mirror of
https://github.com/espressif/openthread.git
synced 2026-08-29 13:29:54 +00:00
[meshcop] support Thread 1.2 Security Policy flags (#6320)
This commit is contained in:
@@ -131,22 +131,20 @@ typedef struct otPskc otPskc;
|
||||
*/
|
||||
typedef struct otSecurityPolicy
|
||||
{
|
||||
uint16_t mRotationTime; ///< The value for thrKeyRotation in units of hours
|
||||
uint8_t mFlags; ///< Flags as defined in Thread 1.1 Section 8.10.1.15
|
||||
} otSecurityPolicy;
|
||||
uint16_t mRotationTime; ///< The value for thrKeyRotation in units of hours.
|
||||
|
||||
/**
|
||||
* This enumeration defines the Security Policy TLV flags.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
OT_SECURITY_POLICY_OBTAIN_MASTER_KEY = 1 << 7, ///< Obtaining the Master Key
|
||||
OT_SECURITY_POLICY_NATIVE_COMMISSIONING = 1 << 6, ///< Native Commissioning
|
||||
OT_SECURITY_POLICY_ROUTERS = 1 << 5, ///< Routers enabled
|
||||
OT_SECURITY_POLICY_EXTERNAL_COMMISSIONER = 1 << 4, ///< External Commissioner allowed
|
||||
OT_SECURITY_POLICY_BEACONS = 1 << 3, ///< Beacons enabled
|
||||
};
|
||||
bool mObtainMasterKeyEnabled : 1; ///< Obtaining the Master Key for out-of-band commissioning is enabled
|
||||
bool mNativeCommissioningEnabled : 1; ///< Native Commissioning using PSKc is allowed
|
||||
bool mRoutersEnabled : 1; ///< Thread 1.0/1.1.x Routers are enabled
|
||||
bool mExternalCommissioningEnabled : 1; ///< External Commissioner authentication is allowed
|
||||
bool mBeaconsEnabled : 1; ///< Thread 1.0/1.1.x Beacons are enabled
|
||||
bool mCommercialCommissioningEnabled : 1; ///< Commercial Commissioning is enabled
|
||||
bool mAutonomousEnrollmentEnabled : 1; ///< Autonomous Enrollment is enabled
|
||||
bool mMasterKeyProvisioningEnabled : 1; ///< Network Master-key Provisioning is enabled
|
||||
bool mTobleLinkEnabled : 1; ///< ToBLE link is enabled
|
||||
bool mNonCcmRoutersEnabled : 1; ///< Non-CCM Routers enabled
|
||||
uint8_t mVersionThresholdForRouting : 3; ///< Version-threshold for Routing
|
||||
} otSecurityPolicy;
|
||||
|
||||
/**
|
||||
* This type represents Channel Mask.
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (99)
|
||||
#define OPENTHREAD_API_VERSION (100)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -366,7 +366,7 @@ Usage: `dataset mgmtgetcommand <active|pending> [address <destination>] [TLV lis
|
||||
Send MGMT_ACTIVE_GET or MGMT_PENDING_GET.
|
||||
|
||||
```bash
|
||||
> dataset mgmtgetcommand active address fdde:ad00:beef:0:558:f56b:d688:799 activetimestamp -x 0c030001ff
|
||||
> dataset mgmtgetcommand active address fdde:ad00:beef:0:558:f56b:d688:799 activetimestamp securitypolicy
|
||||
Done
|
||||
```
|
||||
|
||||
@@ -377,7 +377,7 @@ Usage: `dataset mgmtsetcommand <active|pending> [TLV Type list] [-x]`
|
||||
Send MGMT_ACTIVE_SET or MGMT_PENDING_SET.
|
||||
|
||||
```bash
|
||||
> dataset mgmtsetcommand active activetimestamp 123 -x 0c030001ff
|
||||
> dataset mgmtsetcommand active activetimestamp 123 securitypolicy 1 onrcb
|
||||
Done
|
||||
```
|
||||
|
||||
@@ -496,7 +496,7 @@ Done
|
||||
|
||||
### securitypolicy
|
||||
|
||||
Usage: `dataset securitypolicy [<rotationtime> [onrcb]]`
|
||||
Usage: `dataset securitypolicy [<rotationtime> [onrcbCepR]]`
|
||||
|
||||
Get security policy.
|
||||
|
||||
@@ -513,6 +513,10 @@ Set security policy.
|
||||
- r: Thread 1.x Routers are enabled.
|
||||
- c: External Commissioner authentication is allowed using PSKc.
|
||||
- b: Thread 1.x Beacons are enabled.
|
||||
- C: Thread 1.2 Commercial Commissioning is enabled.
|
||||
- e: Thread 1.2 Autonomous Enrollment is enabled.
|
||||
- p: Thread 1.2 Network Master Key Provisioning is enabled.
|
||||
- R: Non-CCM routers are allowed in Thread 1.2 CCM networks.
|
||||
|
||||
```bash
|
||||
> dataset securitypolicy 672 onrcb
|
||||
|
||||
+130
-89
@@ -126,33 +126,8 @@ otError Dataset::Print(otOperationalDataset &aDataset)
|
||||
|
||||
if (aDataset.mComponents.mIsSecurityPolicyPresent)
|
||||
{
|
||||
mInterpreter.OutputFormat("Security Policy: %d, ", aDataset.mSecurityPolicy.mRotationTime);
|
||||
|
||||
if (aDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_OBTAIN_MASTER_KEY)
|
||||
{
|
||||
mInterpreter.OutputFormat("o");
|
||||
}
|
||||
|
||||
if (aDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_NATIVE_COMMISSIONING)
|
||||
{
|
||||
mInterpreter.OutputFormat("n");
|
||||
}
|
||||
|
||||
if (aDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_ROUTERS)
|
||||
{
|
||||
mInterpreter.OutputFormat("r");
|
||||
}
|
||||
|
||||
if (aDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_EXTERNAL_COMMISSIONER)
|
||||
{
|
||||
mInterpreter.OutputFormat("c");
|
||||
}
|
||||
|
||||
if (aDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_BEACONS)
|
||||
{
|
||||
mInterpreter.OutputFormat("b");
|
||||
}
|
||||
|
||||
mInterpreter.OutputFormat("Security Policy: ", aDataset.mSecurityPolicy.mRotationTime);
|
||||
OutputSecurityPolicy(aDataset.mSecurityPolicy);
|
||||
mInterpreter.OutputLine("");
|
||||
}
|
||||
|
||||
@@ -620,6 +595,14 @@ otError Dataset::ProcessMgmtSetCommand(uint8_t aArgsLength, char *aArgs[])
|
||||
dataset.mComponents.mIsChannelMaskPresent = true;
|
||||
SuccessOrExit(error = ParseAsUint32(aArgs[index], dataset.mChannelMask));
|
||||
}
|
||||
else if (strcmp(aArgs[index], "securitypolicy") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = ParseSecurityPolicy(dataset.mSecurityPolicy, aArgs[index],
|
||||
index + 1 < aArgsLength ? aArgs[index + 1] : nullptr));
|
||||
dataset.mComponents.mIsSecurityPolicyPresent = true;
|
||||
++index;
|
||||
}
|
||||
else if (strcmp(aArgs[index], "-x") == 0)
|
||||
{
|
||||
uint16_t length;
|
||||
@@ -703,6 +686,10 @@ otError Dataset::ProcessMgmtGetCommand(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
datasetComponents.mIsChannelPresent = true;
|
||||
}
|
||||
else if (strcmp(aArgs[index], "securitypolicy") == 0)
|
||||
{
|
||||
datasetComponents.mIsSecurityPolicyPresent = true;
|
||||
}
|
||||
else if (strcmp(aArgs[index], "-x") == 0)
|
||||
{
|
||||
uint16_t length;
|
||||
@@ -784,6 +771,119 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Dataset::OutputSecurityPolicy(const otSecurityPolicy &aSecurityPolicy)
|
||||
{
|
||||
mInterpreter.OutputFormat("%d ", aSecurityPolicy.mRotationTime);
|
||||
|
||||
if (aSecurityPolicy.mObtainMasterKeyEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("o");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mNativeCommissioningEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("n");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mRoutersEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("r");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mExternalCommissioningEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("c");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mBeaconsEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("b");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mCommercialCommissioningEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("C");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mAutonomousEnrollmentEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("e");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mMasterKeyProvisioningEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("p");
|
||||
}
|
||||
|
||||
if (aSecurityPolicy.mNonCcmRoutersEnabled)
|
||||
{
|
||||
mInterpreter.OutputFormat("R");
|
||||
}
|
||||
}
|
||||
|
||||
Error Dataset::ParseSecurityPolicy(otSecurityPolicy &aSecurityPolicy, const char *aRotation, const char *aFlags)
|
||||
{
|
||||
Error error;
|
||||
otSecurityPolicy policy;
|
||||
|
||||
memset(&policy, 0, sizeof(policy));
|
||||
SuccessOrExit(error = ParseAsUint16(aRotation, policy.mRotationTime));
|
||||
|
||||
VerifyOrExit(aFlags != nullptr);
|
||||
|
||||
for (const char *flag = aFlags; *flag != '\0'; flag++)
|
||||
{
|
||||
switch (*flag)
|
||||
{
|
||||
case 'o':
|
||||
policy.mObtainMasterKeyEnabled = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
policy.mNativeCommissioningEnabled = true;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
policy.mRoutersEnabled = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
policy.mExternalCommissioningEnabled = true;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
policy.mBeaconsEnabled = true;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
policy.mCommercialCommissioningEnabled = true;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
policy.mAutonomousEnrollmentEnabled = true;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
policy.mMasterKeyProvisioningEnabled = true;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
policy.mNonCcmRoutersEnabled = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
if (error == kErrorNone)
|
||||
{
|
||||
aSecurityPolicy = policy;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Dataset::ProcessSecurityPolicy(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -792,73 +892,14 @@ otError Dataset::ProcessSecurityPolicy(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
if (sDataset.mComponents.mIsSecurityPolicyPresent)
|
||||
{
|
||||
mInterpreter.OutputFormat("%d ", sDataset.mSecurityPolicy.mRotationTime);
|
||||
|
||||
if (sDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_OBTAIN_MASTER_KEY)
|
||||
{
|
||||
mInterpreter.OutputFormat("o");
|
||||
}
|
||||
|
||||
if (sDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_NATIVE_COMMISSIONING)
|
||||
{
|
||||
mInterpreter.OutputFormat("n");
|
||||
}
|
||||
|
||||
if (sDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_ROUTERS)
|
||||
{
|
||||
mInterpreter.OutputFormat("r");
|
||||
}
|
||||
|
||||
if (sDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_EXTERNAL_COMMISSIONER)
|
||||
{
|
||||
mInterpreter.OutputFormat("c");
|
||||
}
|
||||
|
||||
if (sDataset.mSecurityPolicy.mFlags & OT_SECURITY_POLICY_BEACONS)
|
||||
{
|
||||
mInterpreter.OutputFormat("b");
|
||||
}
|
||||
|
||||
OutputSecurityPolicy(sDataset.mSecurityPolicy);
|
||||
mInterpreter.OutputLine("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = ParseAsUint16(aArgs[0], sDataset.mSecurityPolicy.mRotationTime));
|
||||
sDataset.mSecurityPolicy.mFlags = 0;
|
||||
|
||||
if (aArgsLength > 1)
|
||||
{
|
||||
for (char *arg = aArgs[1]; *arg != '\0'; arg++)
|
||||
{
|
||||
switch (*arg)
|
||||
{
|
||||
case 'o':
|
||||
sDataset.mSecurityPolicy.mFlags |= OT_SECURITY_POLICY_OBTAIN_MASTER_KEY;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
sDataset.mSecurityPolicy.mFlags |= OT_SECURITY_POLICY_NATIVE_COMMISSIONING;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
sDataset.mSecurityPolicy.mFlags |= OT_SECURITY_POLICY_ROUTERS;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
sDataset.mSecurityPolicy.mFlags |= OT_SECURITY_POLICY_EXTERNAL_COMMISSIONER;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
sDataset.mSecurityPolicy.mFlags |= OT_SECURITY_POLICY_BEACONS;
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(
|
||||
error = ParseSecurityPolicy(sDataset.mSecurityPolicy, aArgs[0], aArgsLength > 1 ? aArgs[1] : nullptr));
|
||||
sDataset.mComponents.mIsSecurityPolicyPresent = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,9 @@ private:
|
||||
void HandleDatasetUpdater(otError aError);
|
||||
#endif
|
||||
|
||||
void OutputSecurityPolicy(const otSecurityPolicy &aSecurityPolicy);
|
||||
Error ParseSecurityPolicy(otSecurityPolicy &aSecurityPolicy, const char *aRotation, const char *aFlags);
|
||||
|
||||
static constexpr Command sCommands[] = {
|
||||
{"active", &Dataset::ProcessActive},
|
||||
{"activetimestamp", &Dataset::ProcessActiveTimestamp},
|
||||
|
||||
@@ -931,7 +931,7 @@ TxFrame *Mac::PrepareBeacon(void)
|
||||
|
||||
beaconPayload = reinterpret_cast<BeaconPayload *>(beacon->GetPayload());
|
||||
|
||||
if (Get<KeyManager>().IsThreadBeaconEnabled())
|
||||
if (Get<KeyManager>().GetSecurityPolicy().mBeaconsEnabled)
|
||||
{
|
||||
beaconPayload->Init();
|
||||
|
||||
|
||||
@@ -67,12 +67,11 @@ Error Dataset::Info::GenerateRandom(Instance &aInstance)
|
||||
|
||||
Clear();
|
||||
|
||||
mActiveTimestamp = 1;
|
||||
mChannel = preferredChannels.ChooseRandomChannel();
|
||||
mChannelMask = supportedChannels.GetMask();
|
||||
mSecurityPolicy.mRotationTime = KeyManager::kDefaultKeyRotationTime;
|
||||
mSecurityPolicy.mFlags = KeyManager::kDefaultSecurityPolicyFlags;
|
||||
mPanId = Mac::GenerateRandomPanId();
|
||||
mActiveTimestamp = 1;
|
||||
mChannel = preferredChannels.ChooseRandomChannel();
|
||||
mChannelMask = supportedChannels.GetMask();
|
||||
mPanId = Mac::GenerateRandomPanId();
|
||||
static_cast<SecurityPolicy &>(mSecurityPolicy).SetToDefault();
|
||||
|
||||
SuccessOrExit(error = static_cast<MasterKey &>(mMasterKey).GenerateRandom());
|
||||
SuccessOrExit(error = static_cast<Pskc &>(mPskc).GenerateRandom());
|
||||
@@ -137,9 +136,7 @@ bool Dataset::Info::IsSubsetOf(const Info &aOther) const
|
||||
|
||||
if (IsSecurityPolicyPresent())
|
||||
{
|
||||
VerifyOrExit(aOther.IsSecurityPolicyPresent() &&
|
||||
GetSecurityPolicy().mRotationTime == aOther.GetSecurityPolicy().mRotationTime &&
|
||||
GetSecurityPolicy().mFlags == aOther.GetSecurityPolicy().mFlags);
|
||||
VerifyOrExit(aOther.IsSecurityPolicyPresent() && GetSecurityPolicy() == aOther.GetSecurityPolicy());
|
||||
}
|
||||
|
||||
if (IsChannelMaskPresent())
|
||||
@@ -249,7 +246,8 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
|
||||
case Tlv::kSecurityPolicy:
|
||||
{
|
||||
const SecurityPolicyTlv *tlv = static_cast<const SecurityPolicyTlv *>(cur);
|
||||
aDatasetInfo.SetSecurityPolicy(tlv->GetRotationTime(), tlv->GetFlags());
|
||||
|
||||
aDatasetInfo.SetSecurityPolicy(tlv->GetSecurityPolicy());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -363,9 +361,9 @@ Error Dataset::SetFrom(const Info &aDatasetInfo)
|
||||
if (aDatasetInfo.IsSecurityPolicyPresent())
|
||||
{
|
||||
SecurityPolicyTlv tlv;
|
||||
|
||||
tlv.Init();
|
||||
tlv.SetRotationTime(aDatasetInfo.GetSecurityPolicy().mRotationTime);
|
||||
tlv.SetFlags(aDatasetInfo.GetSecurityPolicy().mFlags);
|
||||
tlv.SetSecurityPolicy(aDatasetInfo.GetSecurityPolicy());
|
||||
IgnoreError(SetTlv(tlv));
|
||||
}
|
||||
|
||||
@@ -593,8 +591,7 @@ Error Dataset::ApplyConfiguration(Instance &aInstance, bool *aIsMasterKeyUpdated
|
||||
case Tlv::kSecurityPolicy:
|
||||
{
|
||||
const SecurityPolicyTlv *securityPolicy = static_cast<const SecurityPolicyTlv *>(cur);
|
||||
IgnoreError(keyManager.SetKeyRotation(securityPolicy->GetRotationTime()));
|
||||
keyManager.SetSecurityPolicyFlags(securityPolicy->GetFlags());
|
||||
keyManager.SetSecurityPolicy(securityPolicy->GetSecurityPolicy());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -534,20 +534,9 @@ public:
|
||||
* @returns The Security Policy in the Dataset.
|
||||
*
|
||||
*/
|
||||
const otSecurityPolicy &GetSecurityPolicy(void) const { return mSecurityPolicy; }
|
||||
|
||||
/**
|
||||
* This method sets the Security Policy in the Dataset.
|
||||
*
|
||||
* @param[in] aRotationTime A value for Key Rotation (in units of hours).
|
||||
* @param[in] aFlags Security policy flags
|
||||
*
|
||||
*/
|
||||
void SetSecurityPolicy(uint16_t aRotationTime, uint8_t aFlags)
|
||||
const SecurityPolicy &GetSecurityPolicy(void) const
|
||||
{
|
||||
mSecurityPolicy.mRotationTime = aRotationTime;
|
||||
mSecurityPolicy.mFlags = aFlags;
|
||||
mComponents.mIsSecurityPolicyPresent = true;
|
||||
return static_cast<const SecurityPolicy &>(mSecurityPolicy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -556,7 +545,7 @@ public:
|
||||
* @param[in] aSecurityPolicy A Security Policy to set in Dataset.
|
||||
*
|
||||
*/
|
||||
void SetSecurityPolicy(const otSecurityPolicy &aSecurityPolicy)
|
||||
void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy)
|
||||
{
|
||||
mSecurityPolicy = aSecurityPolicy;
|
||||
mComponents.mIsSecurityPolicyPresent = true;
|
||||
|
||||
@@ -416,7 +416,8 @@ void DatasetManager::SendGetResponse(const Coap::Message & aRequest,
|
||||
{
|
||||
for (const Tlv *cur = dataset.GetTlvsStart(); cur < dataset.GetTlvsEnd(); cur = cur->GetNext())
|
||||
{
|
||||
if (cur->GetType() != Tlv::kNetworkMasterKey || Get<KeyManager>().IsObtainMasterKeyEnabled())
|
||||
if (cur->GetType() != Tlv::kNetworkMasterKey ||
|
||||
Get<KeyManager>().GetSecurityPolicy().mObtainMasterKeyEnabled)
|
||||
{
|
||||
SuccessOrExit(error = cur->AppendTo(*message));
|
||||
}
|
||||
@@ -428,7 +429,8 @@ void DatasetManager::SendGetResponse(const Coap::Message & aRequest,
|
||||
{
|
||||
const Tlv *tlv;
|
||||
|
||||
if (aTlvs[index] == Tlv::kNetworkMasterKey && !Get<KeyManager>().IsObtainMasterKeyEnabled())
|
||||
if (aTlvs[index] == Tlv::kNetworkMasterKey &&
|
||||
!Get<KeyManager>().GetSecurityPolicy().mObtainMasterKeyEnabled)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -387,9 +387,9 @@ Error ActiveDataset::GenerateLocal(void)
|
||||
if (dataset.GetTlv<SecurityPolicyTlv>() == nullptr)
|
||||
{
|
||||
SecurityPolicyTlv tlv;
|
||||
|
||||
tlv.Init();
|
||||
tlv.SetRotationTime(static_cast<uint16_t>(Get<KeyManager>().GetKeyRotation()));
|
||||
tlv.SetFlags(Get<KeyManager>().GetSecurityPolicyFlags());
|
||||
tlv.SetSecurityPolicy(Get<KeyManager>().GetSecurityPolicy());
|
||||
IgnoreError(dataset.SetTlv(tlv));
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,33 @@ void SteeringDataTlv::CopyTo(SteeringData &aSteeringData) const
|
||||
memcpy(aSteeringData.GetData(), mSteeringData, GetSteeringDataLength());
|
||||
}
|
||||
|
||||
bool SecurityPolicyTlv::IsValid(void) const
|
||||
{
|
||||
return GetLength() >= sizeof(mRotationTime) && GetRotationTime() >= SecurityPolicy::kMinKeyRotationTime &&
|
||||
GetFlagsLength() >= kThread11FlagsLength;
|
||||
}
|
||||
|
||||
SecurityPolicy SecurityPolicyTlv::GetSecurityPolicy(void) const
|
||||
{
|
||||
OT_ASSERT(IsValid());
|
||||
|
||||
SecurityPolicy securityPolicy;
|
||||
uint8_t length = OT_MIN(static_cast<uint8_t>(sizeof(mFlags)), GetFlagsLength());
|
||||
|
||||
securityPolicy.mRotationTime = GetRotationTime();
|
||||
securityPolicy.SetFlags(mFlags, length);
|
||||
|
||||
return securityPolicy;
|
||||
}
|
||||
|
||||
void SecurityPolicyTlv::SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy)
|
||||
{
|
||||
SetRotationTime(aSecurityPolicy.mRotationTime);
|
||||
aSecurityPolicy.GetFlags(mFlags, sizeof(mFlags));
|
||||
|
||||
OT_ASSERT(IsValid());
|
||||
}
|
||||
|
||||
bool ChannelTlv::IsValid(void) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
@@ -971,52 +971,41 @@ public:
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
|
||||
bool IsValid(void) const;
|
||||
|
||||
/**
|
||||
* This method returns the Rotation Time value.
|
||||
* This method returns the Security Policy.
|
||||
*
|
||||
* @returns The Rotation Time value.
|
||||
* @returns The Security Policy.
|
||||
*
|
||||
*/
|
||||
uint16_t GetRotationTime(void) const { return HostSwap16(mRotationTime); }
|
||||
SecurityPolicy GetSecurityPolicy(void) const;
|
||||
|
||||
/**
|
||||
* This method sets the Rotation Time value.
|
||||
* This method sets the Security Policy.
|
||||
*
|
||||
* @param[in] aRotationTime The Rotation Time value.
|
||||
* @param[in] aSecurityPolicy The Security Policy which will be set.
|
||||
*
|
||||
*/
|
||||
void SetRotationTime(uint16_t aRotationTime) { mRotationTime = HostSwap16(aRotationTime); }
|
||||
|
||||
enum
|
||||
{
|
||||
kObtainMasterKeyFlag = OT_SECURITY_POLICY_OBTAIN_MASTER_KEY, ///< Obtaining the Master Key
|
||||
kNativeCommissioningFlag = OT_SECURITY_POLICY_NATIVE_COMMISSIONING, ///< Native Commissioning
|
||||
kRoutersFlag = OT_SECURITY_POLICY_ROUTERS, ///< Routers enabled
|
||||
kExternalCommissionerFlag = OT_SECURITY_POLICY_EXTERNAL_COMMISSIONER, ///< External Commissioner allowed
|
||||
kBeaconsFlag = OT_SECURITY_POLICY_BEACONS, ///< Beacons enabled
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns the Flags value.
|
||||
*
|
||||
* @returns The Flags value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetFlags(void) const { return mFlags; }
|
||||
|
||||
/**
|
||||
* This method sets the Flags value.
|
||||
*
|
||||
* @param[in] aFlags The Flags value.
|
||||
*
|
||||
*/
|
||||
void SetFlags(uint8_t aFlags) { mFlags = aFlags; }
|
||||
void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy);
|
||||
|
||||
private:
|
||||
enum : uint8_t
|
||||
{
|
||||
kThread11FlagsLength = 1, ///< The Thread 1.1 Security Policy Flags length.
|
||||
kThread12FlagsLength = 2, ///< The Thread 1.2 Security Policy Flags length.
|
||||
};
|
||||
|
||||
void SetRotationTime(uint16_t aRotationTime) { mRotationTime = HostSwap16(aRotationTime); }
|
||||
uint16_t GetRotationTime(void) const { return HostSwap16(mRotationTime); }
|
||||
uint8_t GetFlagsLength(void) const { return GetLength() - sizeof(mRotationTime); }
|
||||
|
||||
uint16_t mRotationTime;
|
||||
uint8_t mFlags;
|
||||
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
uint8_t mFlags[kThread12FlagsLength];
|
||||
#else
|
||||
uint8_t mFlags[kThread11FlagsLength];
|
||||
#endif
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
|
||||
+114
-16
@@ -56,6 +56,116 @@ const uint8_t KeyManager::kTrelInfoString[] = {'T', 'h', 'r', 'e', 'a', 'd', 'O'
|
||||
'r', 'I', 'n', 'f', 'r', 'a', 'K', 'e', 'y'};
|
||||
#endif
|
||||
|
||||
void SecurityPolicy::SetToDefault(void)
|
||||
{
|
||||
mRotationTime = kDefaultKeyRotationTime;
|
||||
SetToDefaultFlags();
|
||||
}
|
||||
|
||||
void SecurityPolicy::SetToDefaultFlags(void)
|
||||
{
|
||||
mObtainMasterKeyEnabled = true;
|
||||
mNativeCommissioningEnabled = true;
|
||||
mRoutersEnabled = true;
|
||||
mExternalCommissioningEnabled = true;
|
||||
mBeaconsEnabled = true;
|
||||
mCommercialCommissioningEnabled = false;
|
||||
mAutonomousEnrollmentEnabled = false;
|
||||
mMasterKeyProvisioningEnabled = false;
|
||||
mTobleLinkEnabled = true;
|
||||
mNonCcmRoutersEnabled = false;
|
||||
mVersionThresholdForRouting = 0;
|
||||
}
|
||||
|
||||
void SecurityPolicy::SetFlags(const uint8_t *aFlags, uint8_t aFlagsLength)
|
||||
{
|
||||
OT_ASSERT(aFlagsLength > 0);
|
||||
|
||||
SetToDefaultFlags();
|
||||
|
||||
mObtainMasterKeyEnabled = aFlags[0] & kObtainMasterKeyMask;
|
||||
mNativeCommissioningEnabled = aFlags[0] & kNativeCommissioningMask;
|
||||
mRoutersEnabled = aFlags[0] & kRoutersMask;
|
||||
mExternalCommissioningEnabled = aFlags[0] & kExternalCommissioningMask;
|
||||
mBeaconsEnabled = aFlags[0] & kBeaconsMask;
|
||||
mCommercialCommissioningEnabled = (aFlags[0] & kCommercialCommissioningMask) == 0;
|
||||
mAutonomousEnrollmentEnabled = (aFlags[0] & kAutonomousEnrollmentMask) == 0;
|
||||
mMasterKeyProvisioningEnabled = (aFlags[0] & kMasterKeyProvisioningMask) == 0;
|
||||
|
||||
VerifyOrExit(aFlagsLength > sizeof(aFlags[0]));
|
||||
mTobleLinkEnabled = aFlags[1] & kTobleLinkMask;
|
||||
mNonCcmRoutersEnabled = (aFlags[1] & kNonCcmRoutersMask) == 0;
|
||||
mVersionThresholdForRouting = aFlags[1] & kVersionThresholdForRoutingMask;
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void SecurityPolicy::GetFlags(uint8_t *aFlags, uint8_t aFlagsLength) const
|
||||
{
|
||||
OT_ASSERT(aFlagsLength > 0);
|
||||
|
||||
memset(aFlags, 0, aFlagsLength);
|
||||
|
||||
if (mObtainMasterKeyEnabled)
|
||||
{
|
||||
aFlags[0] |= kObtainMasterKeyMask;
|
||||
}
|
||||
|
||||
if (mNativeCommissioningEnabled)
|
||||
{
|
||||
aFlags[0] |= kNativeCommissioningMask;
|
||||
}
|
||||
|
||||
if (mRoutersEnabled)
|
||||
{
|
||||
aFlags[0] |= kRoutersMask;
|
||||
}
|
||||
|
||||
if (mExternalCommissioningEnabled)
|
||||
{
|
||||
aFlags[0] |= kExternalCommissioningMask;
|
||||
}
|
||||
|
||||
if (mBeaconsEnabled)
|
||||
{
|
||||
aFlags[0] |= kBeaconsMask;
|
||||
}
|
||||
|
||||
if (!mCommercialCommissioningEnabled)
|
||||
{
|
||||
aFlags[0] |= kCommercialCommissioningMask;
|
||||
}
|
||||
|
||||
if (!mAutonomousEnrollmentEnabled)
|
||||
{
|
||||
aFlags[0] |= kAutonomousEnrollmentMask;
|
||||
}
|
||||
|
||||
if (!mMasterKeyProvisioningEnabled)
|
||||
{
|
||||
aFlags[0] |= kMasterKeyProvisioningMask;
|
||||
}
|
||||
|
||||
VerifyOrExit(aFlagsLength > sizeof(aFlags[0]));
|
||||
|
||||
if (mTobleLinkEnabled)
|
||||
{
|
||||
aFlags[1] |= kTobleLinkMask;
|
||||
}
|
||||
|
||||
if (!mNonCcmRoutersEnabled)
|
||||
{
|
||||
aFlags[1] |= kNonCcmRoutersMask;
|
||||
}
|
||||
|
||||
aFlags[1] |= kReservedMask;
|
||||
aFlags[1] |= mVersionThresholdForRouting;
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
KeyManager::KeyManager(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mKeySequence(0)
|
||||
@@ -63,12 +173,10 @@ KeyManager::KeyManager(Instance &aInstance)
|
||||
, mStoredMacFrameCounter(0)
|
||||
, mStoredMleFrameCounter(0)
|
||||
, mHoursSinceKeyRotation(0)
|
||||
, mKeyRotationTime(kDefaultKeyRotationTime)
|
||||
, mKeySwitchGuardTime(kDefaultKeySwitchGuardTime)
|
||||
, mKeySwitchGuardEnabled(false)
|
||||
, mKeyRotationTimer(aInstance, KeyManager::HandleKeyRotationTimer)
|
||||
, mKekFrameCounter(0)
|
||||
, mSecurityPolicyFlags(kDefaultSecurityPolicyFlags)
|
||||
, mIsPskcSet(false)
|
||||
{
|
||||
Error error = mMasterKey.GenerateRandom();
|
||||
@@ -298,21 +406,11 @@ void KeyManager::SetKek(const uint8_t *aKek)
|
||||
mKekFrameCounter = 0;
|
||||
}
|
||||
|
||||
Error KeyManager::SetKeyRotation(uint32_t aKeyRotation)
|
||||
void KeyManager::SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy)
|
||||
{
|
||||
Error result = kErrorNone;
|
||||
OT_ASSERT(aSecurityPolicy.mRotationTime >= SecurityPolicy::kMinKeyRotationTime);
|
||||
|
||||
VerifyOrExit(aKeyRotation >= static_cast<uint32_t>(kMinKeyRotationTime), result = kErrorInvalidArgs);
|
||||
|
||||
mKeyRotationTime = aKeyRotation;
|
||||
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
void KeyManager::SetSecurityPolicyFlags(uint8_t aSecurityPolicyFlags)
|
||||
{
|
||||
IgnoreError(Get<Notifier>().Update(mSecurityPolicyFlags, aSecurityPolicyFlags, kEventSecurityPolicyChanged));
|
||||
IgnoreError(Get<Notifier>().Update(mSecurityPolicy, aSecurityPolicy, kEventSecurityPolicyChanged));
|
||||
}
|
||||
|
||||
void KeyManager::StartKeyRotationTimer(void)
|
||||
@@ -339,7 +437,7 @@ void KeyManager::HandleKeyRotationTimer(void)
|
||||
|
||||
mKeyRotationTimer.StartAt(mKeyRotationTimer.GetFireTime(), kOneHourIntervalInMsec);
|
||||
|
||||
if (mHoursSinceKeyRotation >= mKeyRotationTime)
|
||||
if (mHoursSinceKeyRotation >= mSecurityPolicy.mRotationTime)
|
||||
{
|
||||
SetCurrentKeySequence(mKeySequence + 1);
|
||||
}
|
||||
|
||||
+79
-103
@@ -41,6 +41,7 @@
|
||||
#include <openthread/dataset.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
@@ -61,6 +62,72 @@ namespace ot {
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class represents Security Policy Rotation and Flags.
|
||||
*
|
||||
*/
|
||||
class SecurityPolicy : public otSecurityPolicy, public Equatable<SecurityPolicy>
|
||||
{
|
||||
public:
|
||||
enum : uint16_t
|
||||
{
|
||||
kMinKeyRotationTime = 1, ///< The minimum Key Rotation Time in hours.
|
||||
kDefaultKeyRotationTime = 672, ///< Default Key Rotation Time (in unit of hours).
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the object with default Key Rotation Time
|
||||
* and Security Policy Flags.
|
||||
*
|
||||
*/
|
||||
SecurityPolicy(void) { SetToDefault(); }
|
||||
|
||||
/**
|
||||
* This method sets the Security Policy to default values.
|
||||
*
|
||||
*/
|
||||
void SetToDefault(void);
|
||||
|
||||
/**
|
||||
* This method sets the Security Policy Flags.
|
||||
*
|
||||
* @param[in] aFlags The Security Policy Flags.
|
||||
* @param[in] aFlagsLength The length of the Security Policy Flags, 1 byte for
|
||||
* Thread 1.1 devices, and 2 bytes for Thread 1.2 or higher.
|
||||
*
|
||||
*/
|
||||
void SetFlags(const uint8_t *aFlags, uint8_t aFlagsLength);
|
||||
|
||||
/**
|
||||
* This method returns the Security Policy Flags.
|
||||
*
|
||||
* @param[out] aFlags A pointer to the Security Policy Flags buffer.
|
||||
* @param[in] aFlagsLength The length of the Security Policy Flags buffer.
|
||||
*
|
||||
*/
|
||||
void GetFlags(uint8_t *aFlags, uint8_t aFlagsLength) const;
|
||||
|
||||
private:
|
||||
enum : uint8_t
|
||||
{
|
||||
kDefaultFlags = 0xff,
|
||||
kObtainMasterKeyMask = 1 << 7,
|
||||
kNativeCommissioningMask = 1 << 6,
|
||||
kRoutersMask = 1 << 5,
|
||||
kExternalCommissioningMask = 1 << 4,
|
||||
kBeaconsMask = 1 << 3,
|
||||
kCommercialCommissioningMask = 1 << 2,
|
||||
kAutonomousEnrollmentMask = 1 << 1,
|
||||
kMasterKeyProvisioningMask = 1 << 0,
|
||||
kTobleLinkMask = 1 << 7,
|
||||
kNonCcmRoutersMask = 1 << 6,
|
||||
kReservedMask = 0x38,
|
||||
kVersionThresholdForRoutingMask = 0x07,
|
||||
};
|
||||
|
||||
void SetToDefaultFlags(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents a Thread Master Key.
|
||||
*
|
||||
@@ -115,16 +182,6 @@ typedef Mac::Key Kek;
|
||||
class KeyManager : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
enum : uint16_t
|
||||
{
|
||||
kDefaultKeyRotationTime = 672, ///< Default Key Rotation Time (in unit of hours).
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
kDefaultSecurityPolicyFlags = 0xff, ///< Default Security Policy Flags.
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
@@ -365,29 +422,6 @@ public:
|
||||
*/
|
||||
void IncrementKekFrameCounter(void) { mKekFrameCounter++; }
|
||||
|
||||
/**
|
||||
* This method returns the KeyRotation time.
|
||||
*
|
||||
* The KeyRotation time is the time interval after witch security key will be automatically rotated.
|
||||
*
|
||||
* @returns The KeyRotation value in hours.
|
||||
*/
|
||||
uint32_t GetKeyRotation(void) const { return mKeyRotationTime; }
|
||||
|
||||
/**
|
||||
* This method sets the KeyRotation time.
|
||||
*
|
||||
* The KeyRotation time is the time interval after witch security key will be automatically rotated.
|
||||
* Its value shall be larger than or equal to kMinKeyRotationTime.
|
||||
*
|
||||
* @param[in] aKeyRotation The KeyRotation value in hours.
|
||||
*
|
||||
* @retval kErrorNone KeyRotation time updated.
|
||||
* @retval kErrorInvalidArgs @p aKeyRotation is out of range.
|
||||
*
|
||||
*/
|
||||
Error SetKeyRotation(uint32_t aKeyRotation);
|
||||
|
||||
/**
|
||||
* This method returns the KeySwitchGuardTime.
|
||||
*
|
||||
@@ -409,82 +443,26 @@ public:
|
||||
void SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime) { mKeySwitchGuardTime = aKeySwitchGuardTime; }
|
||||
|
||||
/**
|
||||
* This method returns the Security Policy Flags.
|
||||
* This method returns the Security Policy.
|
||||
*
|
||||
* The Security Policy Flags specifies network administrator preferences for which
|
||||
* security-related operations are allowed or disallowed.
|
||||
* The Security Policy specifies Key Rotation Time and network administrator preferences
|
||||
* for which security-related operations are allowed or disallowed.
|
||||
*
|
||||
* @returns The SecurityPolicy Flags.
|
||||
* @returns The SecurityPolicy.
|
||||
*
|
||||
*/
|
||||
uint8_t GetSecurityPolicyFlags(void) const { return mSecurityPolicyFlags; }
|
||||
const SecurityPolicy &GetSecurityPolicy(void) const { return mSecurityPolicy; }
|
||||
|
||||
/**
|
||||
* This method sets the Security Policy Flags.
|
||||
* This method sets the Security Policy.
|
||||
*
|
||||
* The Security Policy Flags specifies network administrator preferences for which
|
||||
* security-related operations are allowed or disallowed.
|
||||
* The Security Policy specifies Key Rotation Time and network administrator preferences
|
||||
* for which security-related operations are allowed or disallowed.
|
||||
*
|
||||
* @param[in] aSecurityPolicyFlags The Security Policy Flags.
|
||||
* @param[in] aSecurityPolicy The Security Policy.
|
||||
*
|
||||
*/
|
||||
void SetSecurityPolicyFlags(uint8_t aSecurityPolicyFlags);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not obtaining Master key for out-of-band is enabled.
|
||||
*
|
||||
* @retval TRUE If obtaining Master key for out-of-band is enabled.
|
||||
* @retval FALSE If obtaining Master key for out-of-band is not enabled.
|
||||
*
|
||||
*/
|
||||
bool IsObtainMasterKeyEnabled(void) const
|
||||
{
|
||||
return (mSecurityPolicyFlags & OT_SECURITY_POLICY_OBTAIN_MASTER_KEY) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not Native Commissioning using PSKc is allowed.
|
||||
*
|
||||
* @retval TRUE If Native Commissioning using PSKc is allowed.
|
||||
* @retval FALSE If Native Commissioning using PSKc is not allowed.
|
||||
*
|
||||
*/
|
||||
bool IsNativeCommissioningAllowed(void) const
|
||||
{
|
||||
return (mSecurityPolicyFlags & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not Thread 1.1 Routers are enabled.
|
||||
*
|
||||
* @retval TRUE If Thread 1.1 Routers are enabled.
|
||||
* @retval FALSE If Thread 1.1 Routers are not enabled.
|
||||
*
|
||||
*/
|
||||
bool IsRouterEnabled(void) const { return (mSecurityPolicyFlags & OT_SECURITY_POLICY_ROUTERS) != 0; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not external Commissioner authentication is allowed using PSKc.
|
||||
*
|
||||
* @retval TRUE If the commissioning sessions by an external Commissioner based on the PSKc are allowed
|
||||
* to be established and that changes to the Commissioner Dataset by on-mesh nodes are allowed.
|
||||
* @retval FALSE If the commissioning sessions by an external Commissioner based on the PSKc are not allowed
|
||||
* to be established and that changes to the Commissioner Dataset by on-mesh nodes are not allowed.
|
||||
*
|
||||
*/
|
||||
bool IsExternalCommissionerAllowed(void) const
|
||||
{
|
||||
return (mSecurityPolicyFlags & OT_SECURITY_POLICY_EXTERNAL_COMMISSIONER) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not Thread Beacons are enabled.
|
||||
*
|
||||
* @retval TRUE If Thread Beacons are enabled.
|
||||
* @retval FALSE If Thread Beacons are not enabled.
|
||||
*
|
||||
*/
|
||||
bool IsThreadBeaconEnabled(void) const { return (mSecurityPolicyFlags & OT_SECURITY_POLICY_BEACONS) != 0; }
|
||||
void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy);
|
||||
|
||||
/**
|
||||
* This method updates the MAC keys and MLE key.
|
||||
@@ -503,7 +481,6 @@ public:
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMinKeyRotationTime = 1,
|
||||
kDefaultKeySwitchGuardTime = 624,
|
||||
kOneHourIntervalInMsec = 3600u * 1000u,
|
||||
};
|
||||
@@ -555,7 +532,6 @@ private:
|
||||
uint32_t mStoredMleFrameCounter;
|
||||
|
||||
uint32_t mHoursSinceKeyRotation;
|
||||
uint32_t mKeyRotationTime;
|
||||
uint32_t mKeySwitchGuardTime;
|
||||
bool mKeySwitchGuardEnabled;
|
||||
TimerMilli mKeyRotationTimer;
|
||||
@@ -566,8 +542,8 @@ private:
|
||||
Kek mKek;
|
||||
uint32_t mKekFrameCounter;
|
||||
|
||||
uint8_t mSecurityPolicyFlags;
|
||||
bool mIsPskcSet : 1;
|
||||
SecurityPolicy mSecurityPolicy;
|
||||
bool mIsPskcSet : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1584,7 +1584,7 @@ void Mle::HandleNotifierEvents(Events aEvents)
|
||||
|
||||
if (aEvents.Contains(kEventSecurityPolicyChanged))
|
||||
{
|
||||
Get<Ip6::Filter>().AllowNativeCommissioner(Get<KeyManager>().IsNativeCommissioningAllowed());
|
||||
Get<Ip6::Filter>().AllowNativeCommissioner(Get<KeyManager>().GetSecurityPolicy().mNativeCommissioningEnabled);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -2907,7 +2907,7 @@ Error MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, const M
|
||||
discoveryResponse.Init();
|
||||
discoveryResponse.SetVersion(kThreadVersion);
|
||||
|
||||
if (Get<KeyManager>().IsNativeCommissioningAllowed())
|
||||
if (Get<KeyManager>().GetSecurityPolicy().mNativeCommissioningEnabled)
|
||||
{
|
||||
SuccessOrExit(error = Tlv::Append<MeshCoP::CommissionerUdpPortTlv>(*message, MeshCoP::kBorderAgentUdpPort));
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "meshcop/dataset.hpp"
|
||||
#include "meshcop/meshcop_tlvs.hpp"
|
||||
#include "radio/radio.hpp"
|
||||
#include "thread/key_manager.hpp"
|
||||
|
||||
#ifndef MS_PER_S
|
||||
#define MS_PER_S 1000
|
||||
@@ -699,8 +700,17 @@ otError RadioSpinel<InterfaceType, ProcessContextType>::ThreadDatasetHandler(con
|
||||
|
||||
case SPINEL_PROP_DATASET_SECURITY_POLICY:
|
||||
{
|
||||
uint8_t flags[2];
|
||||
uint8_t flagsLength = 1;
|
||||
|
||||
SuccessOrExit(error = decoder.ReadUint16(opDataset.mSecurityPolicy.mRotationTime));
|
||||
SuccessOrExit(error = decoder.ReadUint8(opDataset.mSecurityPolicy.mFlags));
|
||||
SuccessOrExit(error = decoder.ReadUint8(flags[0]));
|
||||
if (otThreadGetVersion() >= OT_THREAD_VERSION_1_2 && decoder.GetRemainingLengthInStruct() > 0)
|
||||
{
|
||||
SuccessOrExit(error = decoder.ReadUint8(flags[1]));
|
||||
++flagsLength;
|
||||
}
|
||||
static_cast<SecurityPolicy &>(opDataset.mSecurityPolicy).SetFlags(flags, flagsLength);
|
||||
opDataset.mComponents.mIsSecurityPolicyPresent = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2783,7 +2783,7 @@ enum
|
||||
SPINEL_PROP_DATASET_DELAY_TIMER = SPINEL_PROP_THREAD_EXT__BEGIN + 30,
|
||||
|
||||
/// Operational Dataset Security Policy
|
||||
/** Format: `SC` - No direct read or write
|
||||
/** Format: `SD` - No direct read or write
|
||||
*
|
||||
* It can only be included in one of the Dataset related properties below:
|
||||
*
|
||||
@@ -2797,6 +2797,8 @@ enum
|
||||
* Content is
|
||||
* `S` : Key Rotation Time (in units of hour)
|
||||
* `C` : Security Policy Flags (as specified in Thread 1.1 Section 8.10.1.15)
|
||||
* `C` : Optional Security Policy Flags extension (as specified in Thread 1.2 Section 8.10.1.15).
|
||||
* 0xf8 is used if this field is missing.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_DATASET_SECURITY_POLICY = SPINEL_PROP_THREAD_EXT__BEGIN + 31,
|
||||
|
||||
@@ -1343,10 +1343,17 @@ otError NcpBase::EncodeOperationalDataset(const otOperationalDataset &aDataset)
|
||||
|
||||
if (aDataset.mComponents.mIsSecurityPolicyPresent)
|
||||
{
|
||||
uint8_t flags[2];
|
||||
|
||||
static_cast<const SecurityPolicy &>(aDataset.mSecurityPolicy).GetFlags(flags, sizeof(flags));
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_SECURITY_POLICY));
|
||||
SuccessOrExit(error = mEncoder.WriteUint16(aDataset.mSecurityPolicy.mRotationTime));
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(aDataset.mSecurityPolicy.mFlags));
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(flags[0]));
|
||||
if (otThreadGetVersion() >= OT_THREAD_VERSION_1_2)
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(flags[1]));
|
||||
}
|
||||
SuccessOrExit(error = mEncoder.CloseStruct());
|
||||
}
|
||||
|
||||
@@ -1546,8 +1553,17 @@ otError NcpBase::DecodeOperationalDataset(otOperationalDataset &aDataset,
|
||||
|
||||
if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
|
||||
{
|
||||
uint8_t flags[2];
|
||||
uint8_t flagsLength = 1;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadUint16(aDataset.mSecurityPolicy.mRotationTime));
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(aDataset.mSecurityPolicy.mFlags));
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(flags[0]));
|
||||
if (otThreadGetVersion() >= OT_THREAD_VERSION_1_2 && mDecoder.GetRemainingLengthInStruct() > 0)
|
||||
{
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(flags[1]));
|
||||
++flagsLength;
|
||||
}
|
||||
static_cast<SecurityPolicy &>(aDataset.mSecurityPolicy).SetFlags(flags, flagsLength);
|
||||
}
|
||||
|
||||
aDataset.mComponents.mIsSecurityPolicyPresent = true;
|
||||
|
||||
@@ -137,7 +137,7 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
# Disabling O-Bit security_policy = [3600, 0b01111000]
|
||||
self.nodes[COMMISSIONER_1].send_mgmt_active_set(
|
||||
active_timestamp=15,
|
||||
binary='0c030e1078',
|
||||
security_policy=[3600, 'nrcb'],
|
||||
)
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -148,10 +148,9 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
|
||||
# Step 9
|
||||
# Disabling N-Bit security_policy = [3600, 0b10111000]
|
||||
|
||||
self.nodes[COMMISSIONER_1].send_mgmt_active_set(
|
||||
active_timestamp=20,
|
||||
binary='0c030e10b8',
|
||||
security_policy=[3600, 'orcb'],
|
||||
)
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -166,7 +165,7 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
# Disabling B-Bit security_policy = [3600, 0b11110000]
|
||||
self.nodes[COMMISSIONER_1].send_mgmt_active_set(
|
||||
active_timestamp=25,
|
||||
binary='0c030e10f0',
|
||||
security_policy=[3600, 'onrc'],
|
||||
)
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -181,7 +180,7 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
# Disabling R-Bit security_policy = [3600, 0b11011000]
|
||||
self.nodes[COMMISSIONER_1].send_mgmt_active_set(
|
||||
active_timestamp=30,
|
||||
binary='0c030e10d8',
|
||||
security_policy=[3600, 'oncb'],
|
||||
)
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -218,7 +217,13 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
pkts.filter_wpan_src64(LEADER).\
|
||||
filter_ipv6_dst(COMMISSIONER_1_RLOC).\
|
||||
filter_coap_ack(MGMT_ACTIVE_GET_URI).\
|
||||
filter(lambda p: p.thread_meshcop.tlv.unknown == '0e10f8').\
|
||||
filter(lambda p: (p.thread_meshcop.tlv.sec_policy_rot == 3600 and
|
||||
p.thread_meshcop.tlv.sec_policy_o == 1 and
|
||||
p.thread_meshcop.tlv.sec_policy_n == 1 and
|
||||
p.thread_meshcop.tlv.sec_policy_r == 1 and
|
||||
p.thread_meshcop.tlv.sec_policy_c == 1 and
|
||||
p.thread_meshcop.tlv.sec_policy_b == 1) or
|
||||
(p.thread_meshcop.tlv.unknown == '0e10ff')).\
|
||||
must_next()
|
||||
|
||||
# Step 5: Commissioner_1 sends MGMT_ACTIVE_SET.req to Leader
|
||||
@@ -237,7 +242,8 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
NM_SECURITY_POLICY_TLV
|
||||
} == set(p.thread_meshcop.tlv.type) and\
|
||||
p.thread_meshcop.tlv.active_tstamp == 15 and\
|
||||
p.thread_meshcop.tlv.unknown == '0e1078').\
|
||||
(p.thread_meshcop.tlv.sec_policy_o == 0 or
|
||||
p.thread_meshcop.tlv.unknown == '0e107f')).\
|
||||
must_next()
|
||||
|
||||
# Step 6: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1
|
||||
@@ -289,7 +295,8 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
NM_SECURITY_POLICY_TLV
|
||||
} == set(p.thread_meshcop.tlv.type) and\
|
||||
p.thread_meshcop.tlv.active_tstamp == 20 and\
|
||||
p.thread_meshcop.tlv.unknown == '0e10b8').\
|
||||
(p.thread_meshcop.tlv.sec_policy_n == 0 or
|
||||
p.thread_meshcop.tlv.unknown == '0e10bf')).\
|
||||
must_next()
|
||||
|
||||
# Step 10: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1
|
||||
@@ -326,7 +333,8 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
NM_SECURITY_POLICY_TLV
|
||||
} == set(p.thread_meshcop.tlv.type) and\
|
||||
p.thread_meshcop.tlv.active_tstamp == 25 and\
|
||||
p.thread_meshcop.tlv.unknown == '0e10f0').\
|
||||
(p.thread_meshcop.tlv.sec_policy_b == 0 or
|
||||
p.thread_meshcop.tlv.unknown == '0e10f7')).\
|
||||
must_next()
|
||||
|
||||
# Step 14: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1
|
||||
@@ -371,7 +379,8 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
NM_SECURITY_POLICY_TLV
|
||||
} == set(p.thread_meshcop.tlv.type) and\
|
||||
p.thread_meshcop.tlv.active_tstamp == 30 and\
|
||||
p.thread_meshcop.tlv.unknown == '0e10d8').\
|
||||
(p.thread_meshcop.tlv.sec_policy_r == 0 or
|
||||
p.thread_meshcop.tlv.unknown == '0e10df')).\
|
||||
must_next()
|
||||
|
||||
# Step 18: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1
|
||||
@@ -401,7 +410,8 @@ class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase):
|
||||
filter_mle_cmd(MLE_DATA_RESPONSE).\
|
||||
filter(lambda p:
|
||||
p.mle.tlv.active_tstamp == 30 and\
|
||||
p.thread_meshcop.tlv.unknown == '0e10d8').\
|
||||
(p.thread_meshcop.tlv.sec_policy_r == 0 or
|
||||
p.thread_meshcop.tlv.unknown == '0e10df')).\
|
||||
must_next()
|
||||
|
||||
|
||||
|
||||
@@ -1927,6 +1927,7 @@ class NodeImpl:
|
||||
master_key=None,
|
||||
mesh_local=None,
|
||||
network_name=None,
|
||||
security_policy=None,
|
||||
binary=None,
|
||||
):
|
||||
cmd = 'dataset mgmtsetcommand active '
|
||||
@@ -1955,6 +1956,10 @@ class NodeImpl:
|
||||
if network_name is not None:
|
||||
cmd += 'networkname %s ' % self._escape_escapable(network_name)
|
||||
|
||||
if security_policy is not None:
|
||||
rotation, flags = security_policy
|
||||
cmd += 'securitypolicy %d %s ' % (rotation, flags)
|
||||
|
||||
if binary is not None:
|
||||
cmd += '-x %s ' % binary
|
||||
|
||||
|
||||
@@ -1287,7 +1287,7 @@ class OTCI(object):
|
||||
elif key == 'PSKc':
|
||||
dataset['pskc'] = val
|
||||
elif key == 'Security Policy':
|
||||
rotation_time, flags = val.split(', ')
|
||||
rotation_time, flags = val.split(' ')
|
||||
rotation_time = int(rotation_time)
|
||||
dataset['security_policy'] = SecurityPolicy(rotation_time, flags)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user