Skip to content

Fix Android failure in SslAuthenticationOptionsTests.UpdateOptions_ServerCertificateContextProvided_DoesNotDisposeCallerContext - #131929

Open
rzikm with Copilot wants to merge 2 commits into
mainfrom
copilot/fix-android-test-failure
Open

Fix Android failure in SslAuthenticationOptionsTests.UpdateOptions_ServerCertificateContextProvided_DoesNotDisposeCallerContext#131929
rzikm with Copilot wants to merge 2 commits into
mainfrom
copilot/fix-android-test-failure

Conversation

Copilot AI commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

UpdateOptions_ServerCertificateContextProvided_DoesNotDisposeCallerContext fails on all Android CoreCLR and NativeAOT legs with PlatformNotSupportedException: An empty custom trust store is not supported on this platform.

Android sets ChainBuildNeedsTrustedRoot = true, so when the first X509Chain.Build fails, SslStreamCertificateContext.Create retries with every additionalCertificates entry in ChainPolicy.CustomTrustStore under X509ChainTrustMode.CustomRootTrust. ChainPal.Android only accepts self-issued certificates as trust anchors and routes the rest to the extra store — the test passed only the (non-self-issued) intermediate, leaving the anchor set empty, which Android rejects.

Changes

  • Supply the root as an additional certificate. Both SslStreamCertificateContext.Create calls now receive { intermediateWithKey, rootCert }, giving Android's retry a self-issued trust anchor. This also matches how real callers hand over a chain (see Configuration.Certificates.GenerateCertificates in the functional tests).

    X509Certificate2Collection additionalCertificates =
        new X509Certificate2Collection { intermediateWithKey, rootCert };
  • Relax the intermediate count assertion. Assert.Equal(1, callerContext.IntermediateCertificates.Count)Assert.NotEmpty(...), since TrimRootCertificate is false on Windows and the root stays in the collection there. The per-certificate Export() check — the actual subject of the assertion — is unchanged.

Test-only change; no product code touched. The underlying product behavior (Android throwing PlatformNotSupportedException when a caller supplies intermediates without a root) is pre-existing and left as-is.

Verified on linux-x64: System.Net.Security.Unit.Tests → 137 total, 0 failed. The Android legs could not be exercised locally; the fix is reasoned from ChainPal.Android and needs CI confirmation.

Copilot AI review requested due to automatic review settings August 6, 2026 10:22

Copilot AI 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.

Copilot wasn't able to review any files in this pull request.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

…uding root cert

Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 6, 2026 10:28
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

Copilot AI 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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/libraries/System.Net.Security/tests/UnitTests/SslAuthenticationOptionsTests.cs:234

  • The new Assert.NotEmpty check is a bit too loose for this scenario and doesn’t really encode the stated platform variation (root trimmed vs not). You can keep this robust while still being specific by asserting the expected range for this chain: 1 intermediate on platforms that trim the root, and 2 (intermediate + root) on platforms that keep it.
            // Verify that the caller's intermediate certificates were not disposed
            // (the exact count varies by platform, some platforms keep the root in the chain)
            Assert.NotEmpty(callerContext.IntermediateCertificates);

Copilot AI changed the title [WIP] Fix test failure in SslAuthenticationOptionsTests for Android Fix Android failure in SslAuthenticationOptionsTests.UpdateOptions_ServerCertificateContextProvided_DoesNotDisposeCallerContext Aug 6, 2026
Copilot AI requested a review from rzikm August 6, 2026 10:49
@rzikm

rzikm commented Aug 10, 2026

Copy link
Copy Markdown
Member

/azp list

@azure-pipelines

Copy link
Copy Markdown
CI/CD Pipelines for this repository:

@rzikm

rzikm commented Aug 10, 2026

Copy link
Copy Markdown
Member

/azp run runtime-android

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@rzikm
rzikm marked this pull request as ready for review August 10, 2026 10:16
@rzikm
rzikm requested a review from a team August 10, 2026 10:17
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@rzikm

rzikm commented Aug 11, 2026

Copy link
Copy Markdown
Member

/azp run runtime-android

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@rzikm

rzikm commented Aug 11, 2026

Copy link
Copy Markdown
Member

/ba-g test failures are unrelated

@rzikm

rzikm commented Aug 11, 2026

Copy link
Copy Markdown
Member

The test in question did not fail on the last runtime-android run

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

Projects

None yet

3 participants