Skip to content

Commit 6f1be26

Browse files
AhmedAhmed
authored andcommitted
Fix cross-platform strong name signing by manually parsing RSA key blobs
1 parent f8427ae commit 6f1be26

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

src/Compiler/AbstractIL/ilsign.fs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
22

33
module internal FSharp.Compiler.AbstractIL.StrongNameSign
44

@@ -126,9 +126,7 @@ type BlobReader =
126126
val mutable _blob: byte array
127127
val mutable _offset: int
128128
new(blob: byte array) = { _blob = blob; _offset = 0 }
129-
130-
member x.Offset with get() = x._offset and set(v) = x._offset <- v
131-
129+
132130
member x.ReadInt32() : int =
133131
let offset = x._offset
134132
x._offset <- offset + 4
@@ -147,8 +145,7 @@ type BlobReader =
147145
let RSAParametersFromBlob blob keyType =
148146
let mutable reader = BlobReader blob
149147

150-
let header = reader.ReadInt32()
151-
if header <> 0x00000206 && header <> 0x00000207 && keyType = KeyType.KeyPair then
148+
if reader.ReadInt32() <> 0x00000207 && keyType = KeyType.KeyPair then
152149
raise (CryptographicException(getResourceString (FSComp.SR.ilSignPrivateKeyExpected ())))
153150

154151
reader.ReadInt32() |> ignore // ALG_ID
@@ -303,27 +300,40 @@ let signStream stream keyBlob =
303300
let signature = createSignature hash keyBlob KeyType.KeyPair
304301
patchSignature stream peReader signature
305302

303+
let align8 size = (size + 7) &&& ~~~7
304+
306305
let signatureSize (pk: byte array) =
307-
if pk.Length < 20 then 0
308-
else
309-
let reader = BlobReader pk
310-
reader.Offset <- 12
311-
let bitLen = reader.ReadInt32()
312-
let modulusLength = bitLen / 8
313-
314-
if modulusLength < 160 then 128 else modulusLength - 32
315-
// Key signing
316-
type keyContainerName = string
317-
type keyPair = byte array
318-
type pubkey = byte array
319-
type pubkeyOptions = byte array * bool
306+
if pk.Length < 16 then
307+
raise (CryptographicException(getResourceString (FSComp.SR.ilSignInvalidPKBlob ())))
308+
309+
let reader = BlobReader pk
310+
311+
// Roslyn Logic: Skipping headers directly to get to the bitLen
312+
reader.ReadInt32() |> ignore // Skip PUBLICKEYSTRUC (part 1: bType, bVersion, reserved)
313+
reader.ReadInt32() |> ignore // Skip PUBLICKEYSTRUC (part 2: aiKeyAlg)
314+
reader.ReadInt32() |> ignore // Skip RSAPUBKEY (part 1: magic)
320315

316+
let bitLen = reader.ReadInt32()
317+
318+
if bitLen <= 0 then
319+
raise (CryptographicException(getResourceString (FSComp.SR.ilSignInvalidBitLen ())))
320+
321+
let size = bitLen / 8
322+
align8 size
323+
324+
// Returns a CLR Format Blob public key
321325
let getPublicKeyForKeyPair keyBlob =
322326
use rsa = RSA.Create()
323327
rsa.ImportParameters(RSAParametersFromBlob keyBlob KeyType.KeyPair)
324328
let rsaParameters = rsa.ExportParameters false
325329
toCLRKeyBlob rsaParameters CALG_RSA_KEYX
326330

331+
// Key signing
332+
type keyContainerName = string
333+
type keyPair = byte array
334+
type pubkey = byte array
335+
type pubkeyOptions = byte array * bool
336+
327337
let signerGetPublicKeyForKeyPair (kp: keyPair) : pubkey = getPublicKeyForKeyPair kp
328338

329339
let signerSignatureSize (pk: pubkey) : int = signatureSize pk
@@ -368,7 +378,11 @@ type ILStrongNameSigner =
368378

369379
member s.SignatureSize =
370380
let pkSignatureSize pk =
371-
signerSignatureSize pk
381+
try
382+
signerSignatureSize pk
383+
with exn ->
384+
failwith ("A call to StrongNameSignatureSize failed (" + exn.Message + ")")
385+
0x80
372386

373387
match s with
374388
| PublicKeySigner pk -> pkSignatureSize pk

0 commit comments

Comments
 (0)