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)
{