Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7319590
Explicitly enable FullAssemblySigningSupported for non-Windows builds
aw0lid Jan 22, 2026
6a3d54c
Fix #17451: Update ILStrongNameSigner to support public signing on re…
aw0lid Jan 22, 2026
9ff50eb
Refactor SignatureSize to mirror Roslyn's manual calculation logic
aw0lid Jan 22, 2026
86848a9
Update ilsign.fsi
aw0lid Jan 22, 2026
819a744
Align F# strong-name signer initialization with Roslyn
aw0lid Jan 22, 2026
807f675
Refactor ILStrongNameSigner interface to simplify compiler signing pi…
aw0lid Jan 22, 2026
e192455
feat: update StrongNameSigner to use Roslyn-compatible signature padding
aw0lid Jan 22, 2026
4d76364
Return to the previous state and cancel the modification in this place
aw0lid Jan 22, 2026
8e03ac7
Update ilsign.fsi
aw0lid Jan 22, 2026
8e416a8
Update CreateILModule.fs
aw0lid Jan 22, 2026
dd45d2b
fix: implement deterministic StrongNameSignatureSize mirroring Roslyn
aw0lid Jan 22, 2026
8a0eab1
Update ilsign.fsi
aw0lid Jan 22, 2026
f5b140a
fix: finalize deterministic signature size calculation and remove leg…
aw0lid Jan 22, 2026
5794def
Update CreateILModule.fs
aw0lid Jan 22, 2026
6e55cd7
Update CreateILModule.fs
aw0lid Jan 22, 2026
4327281
Update ilsign.fsi
aw0lid Jan 22, 2026
27ee0e6
Update ilsign.fs
aw0lid Jan 22, 2026
8dcc364
Update ilsign.fsi
aw0lid Jan 23, 2026
ed82e67
Update ilsign.fs
aw0lid Jan 23, 2026
9d6a070
Update CreateILModule.fs
aw0lid Jan 23, 2026
765ae99
fix: explicitly calculate SignatureSize via manual blob parsing to fi…
aw0lid Jan 23, 2026
4002f20
Update ilsign.fsi
aw0lid Jan 23, 2026
5e254bc
Update ilsign.fsi
aw0lid Jan 23, 2026
1e00e91
Update CreateILModule.fs
aw0lid Jan 23, 2026
ad7ab10
Update ilsign.fs
aw0lid Jan 23, 2026
a45a07c
Update ilsign.fsi
aw0lid Jan 23, 2026
4cfbae4
Update CreateILModule.fs
aw0lid Jan 23, 2026
1d8dadb
Update ilsign.fsi
aw0lid Jan 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 67 additions & 61 deletions src/Compiler/AbstractIL/ilsign.fs
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,7 @@ let signStream stream keyBlob =
let signature = createSignature hash keyBlob KeyType.KeyPair
patchSignature stream peReader signature

let signatureSize (pk: byte array) =
if pk.Length < 25 then
raise (CryptographicException(getResourceString (FSComp.SR.ilSignInvalidPKBlob ())))

let mutable reader = BlobReader pk
reader.ReadBigInteger 12 |> ignore // Skip CLRHeader
reader.ReadBigInteger 8 |> ignore // Skip BlobHeader
let magic = reader.ReadInt32() // Read magic

if not (magic = RSA_PRIV_MAGIC || magic = RSA_PUB_MAGIC) then // RSAPubKey.magic
raise (CryptographicException(getResourceString (FSComp.SR.ilSignInvalidPKBlob ())))

let x = reader.ReadInt32() / 8
x

// Returns a CLR Format Blob public key
let getPublicKeyForKeyPair keyBlob =
Expand All @@ -330,65 +317,84 @@ type pubkeyOptions = byte array * bool

let signerGetPublicKeyForKeyPair (kp: keyPair) : pubkey = getPublicKeyForKeyPair kp

let signerSignatureSize (pk: pubkey) : int = signatureSize pk

let signerSignStreamWithKeyPair stream keyBlob = signStream stream keyBlob

let failWithContainerSigningUnsupportedOnThisPlatform () =
failwith (FSComp.SR.containerSigningUnsupportedOnThisPlatform () |> snd)

let signerGetPublicKeyForKeyContainer (_: keyContainerName) : pubkey =
failWithContainerSigningUnsupportedOnThisPlatform ()

let signerSignStreamWithKeyContainer (_: Stream) (_: keyContainerName) =
failWithContainerSigningUnsupportedOnThisPlatform ()

//---------------------------------------------------------------------
// Strong name signing
//---------------------------------------------------------------------
type ILStrongNameSigner =
| PublicKeySigner of pubkey
| PublicKeyOptionsSigner of pubkeyOptions
| KeyPair of keyPair
| KeyContainer of keyContainerName
type internal SignerData =
| PublicKeySigner of byte array
| PublicKeyOptionsSigner of byte array * bool
| KeyPair of byte array * bool
| KeyContainer of string * bool

[<Sealed>]
type ILStrongNameSigner private (data: SignerData) =

static member OpenPublicKeyOptions kp p = PublicKeyOptionsSigner(kp, p)
static member OpenPublicKeyOptions (pk, p) =
ILStrongNameSigner(PublicKeyOptionsSigner(pk, p))

static member OpenPublicKey bytes = PublicKeySigner bytes
static member OpenKeyPairFile bytes = KeyPair(bytes)
static member OpenKeyContainer s = KeyContainer s
static member ExtractPublicKey bytes =
signerGetPublicKeyForKeyPair bytes

member s.IsFullySigned =
match s with
static member OpenPublicKey bytes =
ILStrongNameSigner(PublicKeySigner bytes)

static member OpenKeyPairFile (bytes, ?usePublicSign) =
let ups = defaultArg usePublicSign false
ILStrongNameSigner(KeyPair(bytes, ups))

static member OpenKeyContainer (s, ?usePublicSign) =
let ups = defaultArg usePublicSign false
ILStrongNameSigner(KeyContainer(s, ups))

member _.IsFullySigned =
match data with
| PublicKeySigner _ -> false
| PublicKeyOptionsSigner pko ->
let _, usePublicSign = pko
usePublicSign
| KeyPair _ -> true
| KeyContainer _ -> failWithContainerSigningUnsupportedOnThisPlatform ()

member s.PublicKey =
match s with
| PublicKeyOptionsSigner (_, usePublicSign) -> not usePublicSign
| KeyPair (_, usePublicSign) -> not usePublicSign
| KeyContainer (_, usePublicSign) -> not usePublicSign

member _.PublicKey =
match data with
| PublicKeySigner pk -> pk
| PublicKeyOptionsSigner pko ->
let pk, _ = pko
pk
| KeyPair kp -> signerGetPublicKeyForKeyPair kp
| KeyContainer _ -> failWithContainerSigningUnsupportedOnThisPlatform ()

member s.SignatureSize =
let pkSignatureSize pk =
try
signerSignatureSize pk
with exn ->
failwith ("A call to StrongNameSignatureSize failed (" + exn.Message + ")")
0x80

match s with
| PublicKeySigner pk -> pkSignatureSize pk
| PublicKeyOptionsSigner pko ->
let pk, _ = pko
pkSignatureSize pk
| KeyPair kp -> pkSignatureSize (signerGetPublicKeyForKeyPair kp)
| KeyContainer _ -> failWithContainerSigningUnsupportedOnThisPlatform ()

member s.SignStream stream =
match s with
| PublicKeySigner _ -> ()
| PublicKeyOptionsSigner _ -> ()
| KeyPair kp -> signerSignStreamWithKeyPair stream kp
| KeyContainer _ -> failWithContainerSigningUnsupportedOnThisPlatform ()
| PublicKeyOptionsSigner (pk, _) -> pk
| KeyPair (kp, _) -> signerGetPublicKeyForKeyPair kp
| KeyContainer (kc, _) -> signerGetPublicKeyForKeyContainer kc

member _.SignatureSize =
let calculateFromRaw (pk: byte array) =
if pk = null || pk.Length < 25 then 128
else
try
let bitLen =
int pk.[12]
||| (int pk.[13] <<< 8)
||| (int pk.[14] <<< 16)
||| (int pk.[15] <<< 24)

if bitLen > 0 && bitLen % 8 = 0 then bitLen / 8
else 128
with _ -> 128

match data with
| PublicKeySigner pk
| PublicKeyOptionsSigner (pk, _) -> calculateFromRaw pk
| KeyPair (kp, _) -> calculateFromRaw kp
| KeyContainer (kc, _) -> calculateFromRaw (signerGetPublicKeyForKeyContainer kc)

member _.SignStream stream =
match data with
| KeyPair (kp, false) -> signerSignStreamWithKeyPair stream kp
| KeyContainer (kc, false) -> signerSignStreamWithKeyContainer stream kc
| _ -> ()
10 changes: 5 additions & 5 deletions src/Compiler/AbstractIL/ilsign.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ open System.IO
//---------------------------------------------------------------------
[<Sealed>]
type ILStrongNameSigner =
member PublicKey: byte array
static member OpenPublicKeyOptions: byte array -> bool -> ILStrongNameSigner
static member OpenPublicKeyOptions: byte array * bool -> ILStrongNameSigner
static member OpenPublicKey: byte array -> ILStrongNameSigner
static member OpenKeyPairFile: byte array -> ILStrongNameSigner
static member OpenKeyContainer: string -> ILStrongNameSigner
static member OpenKeyPairFile: byte array * ?usePublicSign: bool -> ILStrongNameSigner
static member OpenKeyContainer: string * ?usePublicSign: bool -> ILStrongNameSigner
static member ExtractPublicKey: byte array -> byte array
member IsFullySigned: bool
member PublicKey: byte array
member SignatureSize: int
member SignStream: Stream -> unit
member SignStream: System.IO.Stream -> unit
8 changes: 4 additions & 4 deletions src/Compiler/Driver/CreateILModule.fs
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,17 @@ let ValidateKeySigningAttributes (tcConfig: TcConfig, tcGlobals, topAttrs) =
/// Get the object used to perform strong-name signing
let GetStrongNameSigner signingInfo =
let (StrongNameSigningInfo(delaysign, publicsign, signer, container)) = signingInfo
// REVIEW: favor the container over the key file - C# appears to do this
match container with
| Some container -> Some(ILStrongNameSigner.OpenKeyContainer container)
| Some container ->
Some(ILStrongNameSigner.OpenKeyContainer (container, publicsign || delaysign))
| None ->
match signer with
| None -> None
| Some bytes ->
if publicsign || delaysign then
Some(ILStrongNameSigner.OpenPublicKeyOptions bytes publicsign)
Some(ILStrongNameSigner.OpenKeyPairFile(bytes, usePublicSign=true))
else
Some(ILStrongNameSigner.OpenKeyPairFile bytes)
Some(ILStrongNameSigner.OpenKeyPairFile(bytes, usePublicSign=false))

//----------------------------------------------------------------------------
// Building the contents of the finalized IL module
Expand Down
Loading