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 72% rename from src/SignCheck/Microsoft.SignCheck/Verification/LinuxPackageVerifier.cs rename to src/SignCheck/Microsoft.SignCheck/Verification/PgpVerifier.cs index 12986efc5b0..523a935dcda 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/LinuxPackageVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/PgpVerifier.cs @@ -10,9 +10,12 @@ 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) { } + protected PgpVerifier(Log log, Exclusions exclusions, SignatureVerificationOptions options, string fileExtension) + : base(log, exclusions, options, fileExtension) + { + } public override SignatureVerificationResult VerifySignature(string path, string parent, string virtualPath) => VerifySupportedFileType(path, parent, virtualPath); @@ -21,16 +24,39 @@ public override SignatureVerificationResult VerifySignature(string path, string /// Returns the paths to the signature document and the signable content. /// Used to verify the signature of the package using gpg. /// - /// - /// - /// protected abstract (string signatureDocument, string signableContent) GetSignatureDocumentAndSignableContent(string path, string tempDir); + /// + /// Verifies the signature of a file using a detached .sig file. + /// If the .sig file exists, verifies as a supported file type; otherwise, as unsupported. + /// + protected SignatureVerificationResult VerifyDetachedSignature(string path, string parent, string virtualPath) + { + if (File.Exists(path + ".sig")) + { + return VerifySupportedFileType(path, parent, virtualPath); + } + return VerifyUnsupportedFileType(path, parent, virtualPath); + } + + /// + /// Returns the paths to the detached signature document and the signable content. + /// For use by verifiers whose signatures are stored in a separate .sig file. + /// + protected static (string signatureDocument, string signableContent) GetDetachedSignatureDocumentAndSignableContent(string path, string tempDir) + { + string signature = $"{path}.sig"; + string signatureDocument = Path.Combine(tempDir, Path.GetFileName(signature)); + File.Copy(signature, signatureDocument, overwrite: true); + + return (signatureDocument, path); + } + 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 79e813203ed..7485dce8842 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/TarVerifier.cs b/src/SignCheck/Microsoft.SignCheck/Verification/TarVerifier.cs index 6f9d38697a0..b52e9909957 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/TarVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/TarVerifier.cs @@ -10,18 +10,21 @@ 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) { 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); + => VerifyDetachedSignature(path, parent, virtualPath); + + protected override (string signatureDocument, string signableContent) GetSignatureDocumentAndSignableContent(string path, string tempDir) + => GetDetachedSignatureDocumentAndSignableContent(path, tempDir); protected override IEnumerable ReadArchiveEntries(string archivePath) { diff --git a/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs b/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs index 510a93ba8b9..cf0565af66c 100644 --- a/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs +++ b/src/SignCheck/Microsoft.SignCheck/Verification/ZipVerifier.cs @@ -8,15 +8,15 @@ 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 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); + => VerifyDetachedSignature(path, parent, virtualPath); + + protected override (string signatureDocument, string signableContent) GetSignatureDocumentAndSignableContent(string path, string tempDir) + => GetDetachedSignatureDocumentAndSignableContent(path, tempDir); protected override IEnumerable ReadArchiveEntries(string archivePath) {