-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add flag and tests for codesigning single-file bundles targeting MacOS #49697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
4f4002d
c0b1c8f
1deba35
8791f6e
44fa49f
8ff3639
7c2fb0e
ea651cb
c8a6d13
ea284a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Runtime.Versioning; | ||
using System.Buffers.Binary; | ||
using System.Diagnostics; | ||
|
||
namespace Microsoft.NET.TestFramework.Utilities | ||
{ | ||
public static class MachOSignature | ||
{ | ||
#if NET | ||
[SupportedOSPlatform("osx")] | ||
#endif | ||
public static bool HasValidMachOSignature(FileInfo file, ITestOutputHelper log) | ||
{ | ||
var codesignPath = @"/usr/bin/codesign"; | ||
return new RunExeCommand(log, codesignPath, "-v", file.FullName) | ||
.Execute().ExitCode == 0; | ||
} | ||
|
||
// Reads the Mach-O load commands and returns true if an LC_CODE_SIGNATURE command is found, otherwise returns false | ||
public static bool HasMachOSignatureLoadCommand(FileInfo file) | ||
{ | ||
/* Mach-O files have the following structure: | ||
* 32 byte header beginning with a magic number and info about the file and load commands | ||
* A series of load commands with the following structure: | ||
* - 4-byte command type | ||
* - 4-byte command size | ||
* - variable length command-specific data | ||
*/ | ||
const uint LC_CODE_SIGNATURE = 0x0000001D; | ||
using (var stream = file.OpenRead()) | ||
{ | ||
// Read the MachO magic number to determine endianness | ||
Span<byte> eightByteBuffer = stackalloc byte[8]; | ||
stream.ReadExactly(eightByteBuffer); | ||
Check failure on line 37 in test/Microsoft.NET.TestFramework/Utilities/MachOSignature.cs
|
||
// Determine if the magic number is in the same or opposite endianness as the runtime | ||
bool reverseEndinanness = BitConverter.ToUInt32(eightByteBuffer.Slice(0, 4)) switch | ||
Check failure on line 39 in test/Microsoft.NET.TestFramework/Utilities/MachOSignature.cs
|
||
{ | ||
0xFEEDFACF => false, | ||
0xCFFAEDFE => true, | ||
_ => throw new InvalidOperationException("Not a 64-bit Mach-O file") | ||
}; | ||
// 4-byte value at offset 16 is the number of load commands | ||
// 4-byte value at offset 20 is the size of the load commands | ||
stream.Position = 16; | ||
ReadUInts(stream, eightByteBuffer, out uint loadCommandsCount, out uint loadCommandsSize); | ||
// Mach-0 64 byte headers are 32 bytes long, and the first load command will be right after | ||
stream.Position = 32; | ||
bool hasSignature = false; | ||
for (int commandIndex = 0; commandIndex < loadCommandsCount; commandIndex++) | ||
{ | ||
ReadUInts(stream, eightByteBuffer, out uint commandType, out uint commandSize); | ||
if (commandType == LC_CODE_SIGNATURE) | ||
{ | ||
hasSignature = true; | ||
} | ||
stream.Position += commandSize - eightByteBuffer.Length; | ||
} | ||
Debug.Assert(stream.Position == loadCommandsSize + 32); | ||
return hasSignature; | ||
|
||
void ReadUInts(Stream stream, Span<byte> buffer, out uint val1, out uint val2) | ||
{ | ||
stream.ReadExactly(buffer); | ||
Check failure on line 66 in test/Microsoft.NET.TestFramework/Utilities/MachOSignature.cs
|
||
val1 = BitConverter.ToUInt32(buffer.Slice(0, 4)); | ||
Check failure on line 67 in test/Microsoft.NET.TestFramework/Utilities/MachOSignature.cs
|
||
val2 = BitConverter.ToUInt32(buffer.Slice(4, 4)); | ||
Check failure on line 68 in test/Microsoft.NET.TestFramework/Utilities/MachOSignature.cs
|
||
if (reverseEndinanness) | ||
{ | ||
val1 = BinaryPrimitives.ReverseEndianness(val1); | ||
val2 = BinaryPrimitives.ReverseEndianness(val2); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.