Skip to content

Fix PublicSign#19442

Open
lewing wants to merge 1 commit intodotnet:mainfrom
lewing:fix-publicsign-private-key-leak
Open

Fix PublicSign#19442
lewing wants to merge 1 commit intodotnet:mainfrom
lewing:fix-publicsign-private-key-leak

Conversation

@lewing
Copy link
Member

@lewing lewing commented Mar 17, 2026

Summary

When PublicSign=true with a full .snk key pair (the default on Linux/macOS for non-official builds), the PublicKey property of PublicKeyOptionsSigner returned the raw .snk bytes verbatim — including all private key material. These bytes were then embedded directly into the compiled assembly's PE metadata.

This caused two problems:

  1. Private key leak: The full RSA private key (P, Q, DP, DQ, InverseQ, D) was embedded in the assembly's metadata blob heap
  2. Malformed public key blob: The blob type byte at offset 12 was 0x07 (PRIVATEKEYBLOB) instead of 0x06 (PUBLICKEYBLOB), causing IsValidPublicKey validation to fail during ResolveAssemblyReference

Root Cause

In GetStrongNameSigner (CreateILModule.fs), when publicsign=true, the raw .snk file bytes are stored in PublicKeyOptionsSigner. The PublicKey property then returned those bytes as-is, without extracting the public key. Compare with the KeyPair case which correctly calls signerGetPublicKeyForKeyPair to strip private material.

Fix

Added isKeyPairBlob to detect raw CAPI PRIVATEKEYBLOB format, and in the PublicKey property, converts key pair blobs to public-key-only CLR blobs via the existing getPublicKeyForKeyPair path.

Impact

This unblocks the dotnet/runtime rolling CI pipeline on Unix legs, where the only F# project (System.Formats.Cbor.Tests.DataModel.fsproj) triggers ResolveAssemblyReference failures across 15 build legs per run.

Tests

  • Strengthened existing PublicSign test to assert no RSA2 (private key) magic in output DLL
  • Added regression test validating AssemblyName.GetAssemblyName() succeeds without SecurityException

Fixes #19441
Regression from #19242

…ssembly

When PublicSign=true with a full .snk key pair, the PublicKey property of
PublicKeyOptionsSigner returned the raw .snk bytes verbatim, including
private key material (PRIVATEKEYBLOB). This caused:

1. Private key material embedded in the compiled assembly's metadata
2. Malformed public key blob (bType=0x07 instead of 0x06) that fails
   IsValidPublicKey validation during ResolveAssemblyReference

The fix detects when PublicKeyOptionsSigner holds a key pair blob and
converts it to a public-key-only CLR blob via getPublicKeyForKeyPair,
matching what the KeyPair case already does.

Also strengthened the existing PublicSign test to verify no RSA2 (private
key) magic appears in the output, and added a regression test that
validates AssemblyName can load the public key without SecurityException.

Fixes dotnet#19441

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

❗ Release notes required

@lewing,

Caution

No release notes found for the changed paths (see table below).

Please make sure to add an entry with an informative description of the change as well as link to this pull request, issue and language suggestion if applicable. Release notes for this repository are based on Keep A Changelog format.

The following format is recommended for this repository:

* <Informative description>. ([PR #XXXXX](https://github.com/dotnet/fsharp/pull/XXXXX))

See examples in the files, listed in the table below or in th full documentation at https://fsharp.github.io/fsharp-compiler-docs/release-notes/About.html.

If you believe that release notes are not necessary for this PR, please add NO_RELEASE_NOTES label to the pull request.

You can open this PR in browser to add release notes: open in github.dev

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/11.0.100.md No release notes found or release notes format is not correct

@lewing lewing changed the title Fix PublicSign with full key pair embedding private key material in assembly Fix PublicSign Mar 17, 2026
@akoeplinger
Copy link
Member

/cc @aw0lid @T-Gro

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

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

PublicSign with full key pair produces assembly with malformed public key blob on Linux

2 participants