Skip to content

chore(tests): Fix flaky nodb tests due to AlgorithmTest#62035

Open
DerDreschner wants to merge 1 commit into
masterfrom
fix/fix-broken-php-nodb-test
Open

chore(tests): Fix flaky nodb tests due to AlgorithmTest#62035
DerDreschner wants to merge 1 commit into
masterfrom
fix/fix-broken-php-nodb-test

Conversation

@DerDreschner

Copy link
Copy Markdown
Contributor

Summary (AI generated)

The failing test AlgorithmTest::testEcdsaP256RoundTrip is a random flake. The chain:

  1. The test helper ecKeyPair() generates a fresh EC key each run and builds a JWK from openssl_pkey_get_details()['ec']['x']/['y'].
  2. PHP returns those coordinates via BN_bn2bin(), which strips leading zero bytes — so ~1 in 256 coordinates comes back 31 bytes instead of 32.
  3. firebase/php-jwt's JWK::parseKey() concatenates the decoded coordinates directly into the uncompressed EC point (0x04 || x || y), which OpenSSL requires to be exactly 65 bytes for P-256. A short coordinate produces a malformed point → the warning openssl_verify(): Supplied key param cannot be coerced into a public key → verify returns false.

RFC 7518 §6.2.1.2 requires JWK coordinates zero-padded to the full field size. Production code already does this correctly (OCMSignatoryManager::buildEcdsaP256JwkArray) — only the test helper forgot.

Why "only on PHP 8.3"?

It actually isn't version-specific — that run was just unlucky. I checked php-src: both PHP 8.3 and 8.5 use the same unpadded BN_bn2bin in openssl_pkey_get_details(). I then ran a 2000-iteration repro in both php:8.3-cli and php:8.5-rc-cli containers: both produced short coordinates at the expected ~0.5–0.9% rate, and every short coordinate failed verification. Each CI job generates its own random keys, so with roughly a 1–3% failure chance per job, the 8.3 job happened to draw a bad key while the 8.5 job didn't. A re-run could just as well have failed on 8.5.

The fix

In tests/lib/Security/Signature/Rfc9421/AlgorithmTest.php, ecKeyPair() now pads both coordinates via a new zeroPadCoordinates() helper (as you suggested) — 32 bytes for P-256, 48 for P-384. Verified: 100 consecutive runs of the ECDSA tests in the dev container, all green, and the repro loop shows zero failures with padding on both PHP versions.

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

Assisted-by: ClaudeCode:claude-fable-5
Signed-off-by: David Dreschner <david.dreschner@nextcloud.com>
@DerDreschner DerDreschner requested a review from a team as a code owner July 13, 2026 03:20
@DerDreschner DerDreschner added 3. to review Waiting for reviews tests Related to tests CI labels Jul 13, 2026
@DerDreschner DerDreschner removed the request for review from a team July 13, 2026 03:20
@DerDreschner DerDreschner changed the title chore(tests): Fix failing nodb tests due to AlgorithmTest chore(tests): Fix flaky nodb tests due to AlgorithmTest Jul 13, 2026
@come-nc

come-nc commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Looks like we do the same thing in the only place I could find in real code that uses ec/x:

$x = str_pad($details['ec']['x'], 32, "\x00", STR_PAD_LEFT);

@mickenordin mickenordin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is my bad, I found this when testing and apparently forgot to update the test :/

@provokateurin

Copy link
Copy Markdown
Member

@DerDreschner

Copy link
Copy Markdown
Contributor Author

@DerDreschner BTW AI written PR descriptions are forbidden: https://github.com/nextcloud/.github/blob/master/AI_POLICY.md#human-written-communication

Ohh, thank you for pointing that out! Will keep that in mind in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews AI assisted CI tests Related to tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants