diff --git a/src/SignCheck/Microsoft.SignCheck/Utils.cs b/src/SignCheck/Microsoft.SignCheck/Utils.cs index fb5e306cc88..e1f0145f617 100644 --- a/src/SignCheck/Microsoft.SignCheck/Utils.cs +++ b/src/SignCheck/Microsoft.SignCheck/Utils.cs @@ -189,7 +189,7 @@ public static (int exitCode, string output, string error) RunBashCommand(string } /// - /// Download the Microsoft and Azure Linux public keys and import them into the keyring. + /// Download the Microsoft, Azure Linux, and .NET release public keys and import them into the keyring. /// public static void DownloadAndConfigurePublicKeys(string tempDir) { @@ -198,7 +198,8 @@ public static void DownloadAndConfigurePublicKeys(string tempDir) "https://packages.microsoft.com/keys/microsoft.asc", // Microsoft public key "https://packages.microsoft.com/keys/microsoft-2025.asc", // Microsoft public key for distributions that do not allow SHA1 "https://packages.microsoft.com/keys/microsoft-rolling.asc", // Non-SHA1 Microsoft public keys for non-Azure Linux distributions - "https://raw.githubusercontent.com/microsoft/azurelinux/3.0/SPECS/azurelinux-repos/MICROSOFT-RPM-GPG-KEY" // Azure linux public key + "https://raw.githubusercontent.com/microsoft/azurelinux/3.0/SPECS/azurelinux-repos/MICROSOFT-RPM-GPG-KEY", // Azure linux public key + "https://dot.net/release-key-2023", // .NET release public key }; foreach (string keyUrl in keyUrls) { diff --git a/src/SignCheck/Microsoft.SignCheck/Verification/DebVerifier.cs b/src/SignCheck/Microsoft.SignCheck/Verification/DebVerifier.cs index 56faaaeff73..a90c9f263ee 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/DebVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/DebVerifier.cs @@ -9,7 +9,7 @@ namespace Microsoft.SignCheck.Verification { - public class DebVerifier : LinuxPackageVerifier + public class DebVerifier : PgpVerifier { public DebVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options) : base(log, exclusions, options, ".deb") { } diff --git a/src/SignCheck/Microsoft.SignCheck/Verification/LinuxPackageVerifier.cs b/src/SignCheck/Microsoft.SignCheck/Verification/PgpVerifier.cs similarity index 73% rename from src/SignCheck/Microsoft.SignCheck/Verification/LinuxPackageVerifier.cs rename to src/SignCheck/Microsoft.SignCheck/Verification/PgpVerifier.cs index 12986efc5b0..1b199091708 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/LinuxPackageVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/PgpVerifier.cs @@ -10,12 +10,24 @@ namespace Microsoft.SignCheck.Verification { - public abstract class LinuxPackageVerifier : ArchiveVerifier + public abstract class PgpVerifier : ArchiveVerifier { - protected LinuxPackageVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options, string fileExtension) : base(log, exclusions, options, fileExtension) { } + private bool _signatureIsDetached; + + protected PgpVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options, string fileExtension, bool signatureIsDetached = false) + : base(log, exclusions, options, fileExtension) + { + _signatureIsDetached = signatureIsDetached; + } public override SignatureVerificationResult VerifySignature(string path, string parent, string virtualPath) - => VerifySupportedFileType(path, parent, virtualPath); + { + if (_signatureIsDetached && File.Exists(path + ".sig")) + { + return VerifySupportedFileType(path, parent, virtualPath); + } + return VerifyUnsupportedFileType(path, parent, virtualPath); + } /// /// Returns the paths to the signature document and the signable content. @@ -24,13 +36,25 @@ public override SignatureVerificationResult VerifySignature(string path, string /// /// /// - protected abstract (string signatureDocument, string signableContent) GetSignatureDocumentAndSignableContent(string path, string tempDir); + protected virtual (string signatureDocument, string signableContent) GetSignatureDocumentAndSignableContent(string path, string tempDir) + { + if (_signatureIsDetached) + { + string signature = $"{path}.sig"; + string signatureDocument = Path.Combine(tempDir, Path.GetFileName(signature)); + File.Copy(signature, signatureDocument, overwrite: true); + + return (signatureDocument, path); + } + + throw new InvalidOperationException("GetSignatureDocumentAndSignableContent must be overridden for supported archive types that do not use detached signatures."); + } protected override bool IsSigned(string path, SignatureVerificationResult svr) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - throw new PlatformNotSupportedException("Linux package verification is not supported on Windows."); + throw new PlatformNotSupportedException("Pgp verification is not supported on Windows."); } string tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); diff --git a/src/SignCheck/Microsoft.SignCheck/Verification/RpmVerifier.cs b/src/SignCheck/Microsoft.SignCheck/Verification/RpmVerifier.cs index 5e80985a668..fe4d4b6115a 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/RpmVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/RpmVerifier.cs @@ -11,7 +11,7 @@ namespace Microsoft.SignCheck.Verification { - public class RpmVerifier : LinuxPackageVerifier + public class RpmVerifier : PgpVerifier { public RpmVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options) : base(log, exclusions, options, ".rpm") { } diff --git a/src/SignCheck/Microsoft.SignCheck/Verification/SignatureVerificationManager.cs b/src/SignCheck/Microsoft.SignCheck/Verification/SignatureVerificationManager.cs index 0354e118acf..f595376002d 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/SignatureVerificationManager.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/SignatureVerificationManager.cs @@ -116,7 +116,7 @@ public SignatureVerificationManager(Exclusions exclusions, Log log, SignatureVer AddFileVerifier(new NupkgVerifier(log, exclusions, options)); AddFileVerifier(new PortableExecutableVerifier(log, exclusions, options, ".dll")); AddFileVerifier(new XmlVerifier(log, exclusions, options)); - AddFileVerifier(new ZipVerifier(log, exclusions, options)); + AddFileVerifier(new ZipVerifier(log, exclusions, options, signatureIsDetached: true)); } /// diff --git a/src/SignCheck/Microsoft.SignCheck/Verification/TarVerifier.cs b/src/SignCheck/Microsoft.SignCheck/Verification/TarVerifier.cs index 6f9d38697a0..2f6196a8af3 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/TarVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/TarVerifier.cs @@ -10,19 +10,16 @@ namespace Microsoft.SignCheck.Verification { - public class TarVerifier : ArchiveVerifier + public class TarVerifier : PgpVerifier { - public TarVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options, string fileExtension) : base(log, exclusions, options, fileExtension) + public TarVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options, string fileExtension) : base(log, exclusions, options, fileExtension, signatureIsDetached: true) { if (fileExtension != ".tar" && fileExtension != ".gz" && fileExtension != ".tgz") { - throw new ArgumentException("fileExtension must be .tar or .gz"); + throw new ArgumentException("fileExtension must be .tar, .gz, or .tgz"); } } - public override SignatureVerificationResult VerifySignature(string path, string parent, string virtualPath) - => VerifyUnsupportedFileType(path, parent, virtualPath); - protected override IEnumerable ReadArchiveEntries(string archivePath) { using (var fileStream = File.Open(archivePath, FileMode.Open)) diff --git a/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs b/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs index 510a93ba8b9..8233d529cdc 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs @@ -8,15 +8,9 @@ namespace Microsoft.SignCheck.Verification { - public class ZipVerifier : ArchiveVerifier + public class ZipVerifier : PgpVerifier { - public ZipVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options, string fileExtension = ".zip") : base(log, exclusions, options, fileExtension) - { - - } - - public override SignatureVerificationResult VerifySignature(string path, string parent, string virtualPath) - => VerifyUnsupportedFileType(path, parent, virtualPath); + public ZipVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options, string fileExtension = ".zip", bool signatureIsDetached = false) : base(log, exclusions, options, fileExtension, signatureIsDetached) { } protected override IEnumerable ReadArchiveEntries(string archivePath) {