File: src\VerifySignatures.cs
Web Access
Project: src\src\Microsoft.DotNet.SignTool\Microsoft.DotNet.SignTool.csproj (Microsoft.DotNet.SignTool)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using NuGet.Common;
using NuGet.Packaging;
using NuGet.Packaging.Signing;
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
 
namespace Microsoft.DotNet.SignTool
{
    internal class VerifySignatures
    {
        internal static bool VerifySignedPowerShellFile(string filePath)
        {
            return File.ReadLines(filePath).Any(line => line.IndexOf("# SIG # Begin Signature Block", StringComparison.OrdinalIgnoreCase) >= 0);
        }
        internal static bool VerifySignedNupkgByFileMarker(string filePath)
        {
            return Path.GetFileName(filePath).Equals(".signature.p7s", StringComparison.OrdinalIgnoreCase);
        }
        internal static bool VerifySignedNupkgIntegrity(string filePath)
        {
            bool isSigned = false;
            using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(filePath)))
            {
                isSigned = SignedPackageArchiveUtility.IsSigned(binaryReader);
#if NETFRAMEWORK
                if (isSigned)
                {
                    try
                    {
                        // A package will fail integrity checks if, for example, the package is signed and then:
                        // - it is repacked
                        // - it has its symbols stripped
                        // - it is otherwise modified
                        using (Stream stream = SignedPackageArchiveUtility.OpenPackageSignatureFileStream(binaryReader))
                        {
                            using (PackageArchiveReader par = new PackageArchiveReader(filePath))
                            {
                                var signature = par.GetPrimarySignatureAsync(CancellationToken.None).Result;
 
                                var task = par.ValidateIntegrityAsync(signature.SignatureContent, CancellationToken.None);
                                task.Wait();
                            }
                        }
                    }
                    catch (Exception)
                    {
                        isSigned = false;
                    }
                }
#endif
            }
            return isSigned;
        }
        internal static bool VerifySignedVSIXByFileMarker(string filePath)
        {
            return filePath.StartsWith("package/services/digital-signature/", StringComparison.OrdinalIgnoreCase);
        }
        internal static bool IsSignedContainer(string fullPath)
        {
            if (FileSignInfo.IsZipContainer(fullPath))
            {
                bool signedContainer = false;
 
                using (var archive = new ZipArchive(File.OpenRead(fullPath), ZipArchiveMode.Read))
                {
                    foreach (ZipArchiveEntry entry in archive.Entries)
                    {
                        if (FileSignInfo.IsNupkg(fullPath) && VerifySignedNupkgByFileMarker(entry.FullName))
                        {
                            if (!VerifySignedNupkgIntegrity(fullPath))
                            {
                                return false;
                            }
                            signedContainer = true;
                            break;
                        }
                        else if (FileSignInfo.IsVsix(fullPath) && VerifySignedVSIXByFileMarker(entry.FullName))
                        {
                            signedContainer = true;
                            break;
                        }
                    }
                }
 
                if (!signedContainer)
                {
                    return false;
                }
            }
            return true;
        }
        internal static bool IsDigitallySigned(string fullPath)
        {
            X509Certificate2 certificate;
            try
            {
                X509Certificate signer = X509Certificate2.CreateFromSignedFile(fullPath);
                certificate = new X509Certificate2(signer);
            }
            catch (Exception)
            {
                return false;
            }
            return certificate.Verify();
        }
    }
}