Skip to content

Commit 9abc432

Browse files
author
Ahmed
committed
Fix cross-platform strong name signing by manually parsing RSA key blobs
1 parent f8427ae commit 9abc432

File tree

1 file changed

+50
-29
lines changed

1 file changed

+50
-29
lines changed

src/Compiler/AbstractIL/ilsign.fs

Lines changed: 50 additions & 29 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,11 @@ 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+
130+
member x.Offset
131+
with get () = x._offset
132+
and set (v) = x._offset <- v
133+
132134
member x.ReadInt32() : int =
133135
let offset = x._offset
134136
x._offset <- offset + 4
@@ -147,14 +149,13 @@ type BlobReader =
147149
let RSAParametersFromBlob blob keyType =
148150
let mutable reader = BlobReader blob
149151

150-
let header = reader.ReadInt32()
151-
if header <> 0x00000206 && header <> 0x00000207 && keyType = KeyType.KeyPair then
152-
raise (CryptographicException(getResourceString (FSComp.SR.ilSignPrivateKeyExpected ())))
152+
reader.ReadInt32() |> ignore
153+
reader.ReadInt32() |> ignore
153154

154-
reader.ReadInt32() |> ignore // ALG_ID
155+
let magic = reader.ReadInt32()
155156

156-
if reader.ReadInt32() <> RSA_PRIV_MAGIC then
157-
raise (CryptographicException(getResourceString (FSComp.SR.ilSignRsaKeyExpected ()))) // 'RSA2'
157+
if magic <> RSA_PUB_MAGIC && magic <> RSA_PRIV_MAGIC then
158+
raise (CryptographicException(getResourceString (FSComp.SR.ilSignRsaKeyExpected ())))
158159

159160
let byteLen, halfLen =
160161
let bitLen = reader.ReadInt32()
@@ -163,15 +164,20 @@ let RSAParametersFromBlob blob keyType =
163164
| 0 -> (bitLen / 8, bitLen / 16)
164165
| _ -> raise (CryptographicException(getResourceString (FSComp.SR.ilSignInvalidBitLen ())))
165166

167+
ignore keyType
168+
166169
let mutable key = RSAParameters()
167170
key.Exponent <- reader.ReadBigInteger 4
168171
key.Modulus <- reader.ReadBigInteger byteLen
169-
key.P <- reader.ReadBigInteger halfLen
170-
key.Q <- reader.ReadBigInteger halfLen
171-
key.DP <- reader.ReadBigInteger halfLen
172-
key.DQ <- reader.ReadBigInteger halfLen
173-
key.InverseQ <- reader.ReadBigInteger halfLen
174-
key.D <- reader.ReadBigInteger byteLen
172+
173+
if magic = RSA_PRIV_MAGIC then
174+
key.P <- reader.ReadBigInteger halfLen
175+
key.Q <- reader.ReadBigInteger halfLen
176+
key.DP <- reader.ReadBigInteger halfLen
177+
key.DQ <- reader.ReadBigInteger halfLen
178+
key.InverseQ <- reader.ReadBigInteger halfLen
179+
key.D <- reader.ReadBigInteger byteLen
180+
175181
key
176182

177183
let validateRSAField (field: byte array MaybeNull) expected (name: string) =
@@ -304,26 +310,42 @@ let signStream stream keyBlob =
304310
patchSignature stream peReader signature
305311

306312
let signatureSize (pk: byte array) =
307-
if pk.Length < 20 then 0
313+
if pk.Length < 20 then
314+
0
308315
else
309316
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
317+
reader.ReadInt32() |> ignore // aiKeyAlg
318+
reader.ReadInt32() |> ignore // aiHashAlg
319+
reader.ReadInt32() |> ignore // keyLen
320+
reader.ReadInt32() |> ignore // bType, bVersion, reserved
321+
let magic = reader.ReadInt32()
322+
323+
if magic = RSA_PUB_MAGIC || magic = RSA_PRIV_MAGIC then
324+
let bitLen = reader.ReadInt32()
325+
let keySizeInBytes = bitLen / 8
326+
327+
if keySizeInBytes < (128 + 32) then
328+
128
329+
else
330+
keySizeInBytes - 32
331+
else if pk.Length < 160 then
332+
128
333+
else
334+
pk.Length - 32
320335

336+
// Returns a CLR Format Blob public key
321337
let getPublicKeyForKeyPair keyBlob =
322338
use rsa = RSA.Create()
323339
rsa.ImportParameters(RSAParametersFromBlob keyBlob KeyType.KeyPair)
324340
let rsaParameters = rsa.ExportParameters false
325341
toCLRKeyBlob rsaParameters CALG_RSA_KEYX
326342

343+
// Key signing
344+
type keyContainerName = string
345+
type keyPair = byte array
346+
type pubkey = byte array
347+
type pubkeyOptions = byte array * bool
348+
327349
let signerGetPublicKeyForKeyPair (kp: keyPair) : pubkey = getPublicKeyForKeyPair kp
328350

329351
let signerSignatureSize (pk: pubkey) : int = signatureSize pk
@@ -367,8 +389,7 @@ type ILStrongNameSigner =
367389
| KeyContainer _ -> failWithContainerSigningUnsupportedOnThisPlatform ()
368390

369391
member s.SignatureSize =
370-
let pkSignatureSize pk =
371-
signerSignatureSize pk
392+
let pkSignatureSize pk = signerSignatureSize pk
372393

373394
match s with
374395
| PublicKeySigner pk -> pkSignatureSize pk

0 commit comments

Comments
 (0)