Skip to content

Clarify when the pairing round count resets - #312

Merged
arturpragacz merged 2 commits into
mainfrom
fix/round-count-reset
Oct 23, 2026
Merged

arturpragacz merged 2 commits into
mainfrom
fix/round-count-reset

Conversation

@maximmaxim345

Copy link
Copy Markdown
Member

The round limit said the operator action that lifts the hold-back also resets the round count, but not whether other operator actions could. A client that resets on an operator action partway through an attempt gives an attacker more than 20 guesses at the same pairing code.

Now only that action or a verified server_kc resets the count.

Comment thread pairing.md Outdated
@arturpragacz
arturpragacz merged commit aaa18a4 into main Oct 23, 2026
1 check passed
@arturpragacz
arturpragacz deleted the fix/round-count-reset branch October 23, 2026 06:34
maximmaxim345 added a commit to Sendspin/sendspin-js that referenced this pull request Oct 27, 2026
# What does this implement/fix?

<!-- Quick description and explanation of changes. -->

A mistyped dynamic pairing code ended the whole pairing attempt, and
after 10 failures every attempt needed the pairing window, with no way
to reset the count.

Now a wrong code starts another round with the same code. After 20
rounds without a correct code, attempts wait until the app calls
`releasePairingHold()` on a deliberate action on the device, which also
resets the count.

This also fixes a few other gaps with the spec:
- The static pairing window now stays open across attempts, so a
timed-out or cancelled attempt no longer needs a new gesture. It closes
on a completed pairing, the fifth wrong code, a drop of the connection
that used it, or `cancelPairing()`.
- Pairing messages that arrive out of sequence now close the connection
instead of being ignored. Messages still in flight after the client's
own `pair/abort` are still dropped.
- The sample player shows the dynamic code as `123-456` and speaks it
with a pause between groups.

This is a breaking change: `isDynamicPinEscalated()` is now
`isRoundLimitReached()`, and `releasePairingHold()` replaces
`openPairingWindow()` for releasing held-back dynamic pairing attempts.

**Related issue or spec PR (if applicable):**

- Sendspin/spec#194
- Sendspin/spec#237
- Sendspin/spec#312

## Types of changes

<!--
Tick exactly one box. CI (.github/workflows/pr-labels.yaml) applies the
matching label, and the release notes use it to sort this change.
-->

- [ ] Bugfix (non-breaking change which fixes an issue): `bugfix`
- [ ] New feature (non-breaking change which adds functionality):
`new-feature`
- [ ] Enhancement to an existing feature: `enhancement`
- [x] Breaking change (changes the public API or the protocol in a way
that is not backwards compatible): `breaking-change`
- [ ] Refactor (no behavior change): `refactor`
- [ ] Documentation only: `documentation`
- [ ] Maintenance / chore: `maintenance`
- [ ] CI / workflow change: `ci`
- [ ] Dependencies bump: `dependencies`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants