Skip to content

Log each TLK share field's type and length when its signature fails - #14

Open
gregakespret wants to merge 1 commit into
fix/mac-escrow-identityfrom
diag/tlkshare-extra-field-log
Open

gregakespret wants to merge 1 commit into
fix/mac-escrow-identityfrom
diag/tlkshare-extra-field-log

Conversation

@gregakespret

Copy link
Copy Markdown
Owner

When a TLK share fails its signature check, the warning now lists every record field in order, instead of names only:

Skipping TLK share for <service>: it failed its signature check (<error>); fields=<n> extras=<k> layout=[<name>:<CloudKit type>:<slot>/<len>[:<marker>], ...]

Markers:

  • superseded: a later field with the same name replaces this one, so it is not signed.
  • extra-signed/<n>: the bytes we signed for an extra field.
  • extra-unsigned, extra-superseded, server, encrypted.

The line never contains a value, only names, types and lengths.

Why. The names-only line shows the failing records carry each of the ten known fields twice and tlkOwnershipProof once. from_record keeps the last copy, so we sign the second copy's values plus the extra. The new line shows two things: whether the two copies differ in type or length, and what CloudKit type the extra arrives as.

Next step: compare with the upstream project's candidate fix. That is an open pull request there that adds extra fields to data_for_signing, and it is not on this branch. On these records, porting it probably would not help:

  • Both build the signed values with from_record, so neither handles a repeated known field.
  • Both sign extras after the positional fields, sorted by key, skipping server_*.
  • It picks an extra's encoding from the CloudKit type tag and skips doubles. This branch goes by which value slot is filled, and signs doubles. They differ only if the layout shows a tag and slot that disagree, or a double.
  • It truncates a date extra to whole seconds. This branch rounds to the millisecond first, as measured on macOS. They differ only for a date extra.
  • It also treats parentKeyRef and wrappedKey as known. The failing records use only the lowercase names.

So if tlkOwnershipProof logs as BYTES_TYPE:bytes/<n>, the two implementations sign the same bytes, and the repeated copy is the lead. If it logs as anything else, port the encoding for that type.

Tests. Three new tests in tlkshare_signing_tests:

  • A repeated field is listed at each occurrence, and the superseded copy is marked.
  • No value reaches the line in any encoding. I checked that this test fails when the layout prints a string value.
  • Each kind of field is listed as signed, skipped or superseded correctly.

cargo test --lib --no-default-features --features remote-anisette-v3 icloud::keychain passes 15 of 15. I did not run the default-feature build.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JvDrSTtCSuxsh3iMaZ8sPX

The names-only warning shows that failing share records carry every known
field twice and the extra field once. It cannot show which copy was signed,
what CloudKit type the extra arrived as, or how many bytes we signed for it.
The warning now lists every field in record order with its type, value slot
and length, marks a copy a later field of the same name supersedes, and gives
each extra's signed length. Values are never logged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JvDrSTtCSuxsh3iMaZ8sPX
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.

1 participant