diff --git a/src/SignCheck/Microsoft.SignCheck/Utils.cs b/src/SignCheck/Microsoft.SignCheck/Utils.cs
index a93733604c4..6c0be5090f4 100644
--- a/src/SignCheck/Microsoft.SignCheck/Utils.cs
+++ b/src/SignCheck/Microsoft.SignCheck/Utils.cs
@@ -193,7 +193,7 @@ public static (int exitCode, string output, string error) RunBashCommand(string
#if NET
///
- /// 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)
{
@@ -202,7 +202,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 70%
rename from src/SignCheck/Microsoft.SignCheck/Verification/LinuxPackageVerifier.cs
rename to src/SignCheck/Microsoft.SignCheck/Verification/PgpVerifier.cs
index 12986efc5b0..a5a1c76f422 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,40 @@ 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 NET
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());
@@ -70,6 +97,9 @@ protected override bool IsSigned(string path, SignatureVerificationResult svr)
{
Directory.Delete(tempDir, true);
}
+#else
+ throw new PlatformNotSupportedException("Pgp verification is not supported on this platform.");
+#endif
}
///
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/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)
{