[cli] add commands for ephemeral key TAP generation and validation (#12267)

This change introduces two new CLI commands to the Border Agent module
for managing Thread Administration One-Time Passcodes (TAPs).

The new commands are:

- `ba ephemeralkey generate-tap`: This command generates and outputs a
  cryptographically secure random TAP string. Note that it does not
  start ephemeral key use with this TAP string.

- `ba ephemeralkey validate-tap <keystring>`: This command validates a
  given TAP string by checking its length, character set, and the
  Verhoeff checksum.

The change also includes documentation updates and a new test case to
verify the functionality.
This commit is contained in:
Abtin Keshavarzian
2026-01-12 10:35:47 -08:00
committed by GitHub
parent 0b0cdc83cf
commit f9aeacfd4d
4 changed files with 110 additions and 1 deletions
+30
View File
@@ -596,6 +596,36 @@ Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE`.
Done
```
### ba ephemeralkey generate-tap
Generates a cryptographically secure random Thread Administration One-Time Passcode (TAP) string.
Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE` and `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
The TAP is a string of 9 characters, generated as a sequence of eight cryptographically secure random numeric digits [`0`-`9`] followed by a single check digit determined using the Verhoeff algorithm.
Note that this command simply generates and outputs a TAP. It does not start ephemeral key use with this TAP on the Border Agent.
```bash
> ba ephemeralkey generate-tap
989710128
Done
```
### ba ephemeralkey validate-tap \<keystring\>
Validates a given Thread Administration One-Time Passcode (TAP) string.
Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE` and `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
Validates that the TAP string has the proper length, contains digit characters [`0`-`9`], and validates the Verhoeff checksum.
```bash
> ba ephemeralkey validate-tap 989710128
validated
Done
```
### ba counters
Get the border agent counter values.
+61 -1
View File
@@ -389,7 +389,7 @@ template <> otError Ba::Process<Cmd("ephemeralkey")>(Arg aArgs[])
{
}
/**
* @cli ba ephemeralkey start <keystring> [timeout-in-msec] [port]
* @cli ba ephemeralkey start
* @code
* ba ephemeralkey start Z10X20g3J15w1000P60m16 5000 1234
* Done
@@ -481,6 +481,66 @@ template <> otError Ba::Process<Cmd("ephemeralkey")>(Arg aArgs[])
otBorderAgentEphemeralKeySetCallback(GetInstancePtr(), nullptr, nullptr);
}
}
#if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
/**
* @cli ba ephemeralkey generate-tap
* @code
* ba ephemeralkey generate-tap
* 989710128
* Done
* @endcode
* @par
* Generates a cryptographically secure random Thread Administration One-Time Passcode (TAP) string.
* @par
* Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE` and `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
* @par
* The TAP is a string of 9 characters, generated as a sequence of eight cryptographically secure random
* numeric digits [`0`-`9`] followed by a single check digit determined using the Verhoeff algorithm.
* @par
* Note that this command simply generates and outputs a TAP. It does not start ephemeral key use with this TAP on
* the Border Agent.
* @sa otBorderAgentEphemeralKeyGenerateTap
*/
else if (aArgs[0] == "generate-tap")
{
otBorderAgentEphemeralKeyTap tap;
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
SuccessOrExit(error = otBorderAgentEphemeralKeyGenerateTap(&tap));
OutputLine("%s", tap.mTap);
}
/**
* @cli ba ephemeralkey validate-tap
* @code
* ba ephemeralkey validate-tap 989710128
* validated
* Done
* @endcode
* @cparam ba ephemeralkey validate-tap @ca{tapstring}
* @par
* Validates a given Thread Administration One-Time Passcode (TAP) string.
* @par
* Requires `OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE` and `OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE`.
* @par
* Validates that the TAP string has the proper length, contains digit characters [`0`-`9`], and validates the
* Verhoeff checksum.
* @sa otBorderAgentEphemeralKeyValidateTap
*/
else if (aArgs[0] == "validate-tap")
{
otBorderAgentEphemeralKeyTap tap;
ClearAllBytes(tap);
VerifyOrExit(!aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aArgs[1].GetLength() <= OT_BORDER_AGENT_EPHEMERAL_KEY_TAP_STRING_LENGTH,
error = OT_ERROR_INVALID_ARGS);
memcpy(tap.mTap, aArgs[1].GetCString(), aArgs[1].GetLength());
SuccessOrExit(error = otBorderAgentEphemeralKeyValidateTap(&tap));
OutputLine("validated");
}
#endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
else
{
error = OT_ERROR_INVALID_ARGS;
+6
View File
@@ -545,6 +545,12 @@ class Node(object):
def ba_ephemeral_key_get_port(self):
return self._cli_single_output('ba ephemeralkey port')
def ba_ephemeral_key_generate_tap(self):
return self._cli_single_output('ba ephemeralkey generate-tap')
def ba_ephemeral_key_validate_tap(self, tapstring):
return self._cli_single_output('ba ephemeralkey validate-tap', tapstring)
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# UDP
@@ -70,6 +70,19 @@ verify(int(leader.ba_ephemeral_key_get_port()) == 1234)
leader.ba_ephemeral_key_stop()
verify(leader.ba_ephemeral_key_get_state() == 'Stopped')
tap = leader.ba_ephemeral_key_generate_tap()
verify(leader.ba_ephemeral_key_validate_tap(tap) == 'validated')
errored = False
try:
leader.ba_ephemeral_key_validate_tap("123456789")
except cli.CliError as e:
verify(e.message == 'Failed')
errored = True
verify(errored)
# -----------------------------------------------------------------------------------------------------------------------
# Test finished