public virtual SignatureVerificationSummary Verify()

in src/NuGet.Core/NuGet.Packaging/Signing/Signatures/Signature.cs [139:347]


        public virtual SignatureVerificationSummary Verify(
            Timestamp timestamp,
            SignatureVerifySettings settings,
            HashAlgorithmName fingerprintAlgorithm,
            X509Certificate2Collection certificateExtraStore)
        {
            settings = settings ?? SignatureVerifySettings.Default;
            var issues = new List<SignatureLog>();
            SignatureVerificationStatus status;

            var certificate = SignerInfo.Certificate;
            if (certificate == null)
            {
                issues.Add(SignatureLog.Issue(!settings.AllowIllegal, NuGetLogCode.NU3010, string.Format(CultureInfo.CurrentCulture, Strings.Verify_ErrorNoCertificate, FriendlyName)));

                status = settings.AllowIllegal ? SignatureVerificationStatus.Valid : SignatureVerificationStatus.Disallowed;
                return new SignatureVerificationSummary(Type, status, SignatureVerificationStatusFlags.NoCertificate, issues);
            }

            issues.Add(SignatureLog.InformationLog(string.Format(CultureInfo.CurrentCulture,
                Strings.VerificationCertDisplay,
                FriendlyName,
                $"{Environment.NewLine}")));

            // Debug log any errors
            issues.AddRange(CertificateUtility.X509Certificate2ToLogMessages(certificate, fingerprintAlgorithm));

            try
            {
                SignerInfo.CheckSignature(verifySignatureOnly: true);
            }
            catch (Exception e)
            {
                issues.Add(SignatureLog.Issue(!settings.AllowIllegal, NuGetLogCode.NU3012, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_SignatureVerificationFailed, FriendlyName)));
                issues.Add(SignatureLog.DebugLog(e.ToString()));
                status = settings.AllowIllegal ? SignatureVerificationStatus.Valid : SignatureVerificationStatus.Disallowed;

                return new SignatureVerificationSummary(Type, status, SignatureVerificationStatusFlags.SignatureCheckFailed, issues);
            }

            DateTimeOffset? expirationTime = null;
            var certificateFlags = VerificationUtility.ValidateSigningCertificate(certificate, !settings.AllowIllegal, FriendlyName, issues);
            if (certificateFlags != SignatureVerificationStatusFlags.NoErrors)
            {
                status = VerificationUtility.GetSignatureVerificationStatus(certificateFlags);
                return new SignatureVerificationSummary(Type, status, certificateFlags, timestamp, expirationTime, issues);
            }
            else
            {
                timestamp = timestamp ?? new Timestamp();
                SignatureVerificationStatusFlags flags = SignatureVerificationStatusFlags.NoErrors;
                using (X509ChainHolder chainHolder = X509ChainHolder.CreateForCodeSigning())
                {
                    IX509Chain chain = chainHolder.Chain2;

                    // This flag should only be set for verification scenarios, not signing.
                    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid;

                    CertificateChainUtility.SetCertBuildChainPolicy(chain.ChainPolicy, certificateExtraStore, timestamp.UpperLimit.LocalDateTime, CertificateType.Signature);

                    if (settings.RevocationMode == RevocationMode.Offline)
                    {
                        chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
                    }
                    else
                    {
                        chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                    }

                    var chainBuildingSucceeded = CertificateChainUtility.BuildCertificateChain(chain, certificate, out var chainStatuses);
                    string x509ChainString = CertificateUtility.X509ChainToString(chain.PrivateReference, fingerprintAlgorithm);

                    if (!string.IsNullOrWhiteSpace(x509ChainString))
                    {
                        issues.Add(SignatureLog.DetailedLog(x509ChainString));
                    }

                    var chainBuildingHasIssues = false;

                    if (!chainBuildingSucceeded && chainStatuses.Length == 0)
                    {
                        return new SignatureVerificationSummary(Type, SignatureVerificationStatus.Unknown, SignatureVerificationStatusFlags.UnknownBuildStatus, timestamp, issues);
                    }

                    var statusFlags = CertificateChainUtility.DefaultObservedStatusFlags;

                    IEnumerable<string> messages;
                    if (CertificateChainUtility.TryGetStatusAndMessage(chainStatuses, statusFlags, out messages))
                    {
                        foreach (var message in messages)
                        {
                            issues.Add(SignatureLog.Issue(!settings.AllowIllegal, NuGetLogCode.NU3012, string.Format(CultureInfo.CurrentCulture, Strings.VerifyChainBuildingIssue, FriendlyName, message)));
                        }

                        chainBuildingHasIssues = true;
                        flags |= SignatureVerificationStatusFlags.ChainBuildingFailure;
                    }

                    // For all the special cases, chain status list only has unique elements for each chain status flag present
                    // therefore if we are checking for one specific chain status we can use the first of the returned list
                    // if we are combining checks for more than one, then we have to use the whole list.
                    if (CertificateChainUtility.TryGetStatusAndMessage(chainStatuses, X509ChainStatusFlags.Revoked, out messages))
                    {
                        issues.Add(SignatureLog.Error(NuGetLogCode.NU3012, string.Format(CultureInfo.CurrentCulture, Strings.VerifyChainBuildingIssue, FriendlyName, messages.First())));
                        flags |= SignatureVerificationStatusFlags.CertificateRevoked;

                        return new SignatureVerificationSummary(Type, SignatureVerificationStatus.Suspect, flags, timestamp, issues);
                    }

                    if (CertificateChainUtility.TryGetStatusAndMessage(chainStatuses, X509ChainStatusFlags.UntrustedRoot, out messages))
                    {
                        if (settings.ReportUntrustedRoot)
                        {
                            SignatureUtility.LogAdditionalContext(chain, issues);

                            issues.Add(SignatureLog.Issue(!settings.AllowUntrusted, NuGetLogCode.NU3018, string.Format(CultureInfo.CurrentCulture, Strings.VerifyChainBuildingIssue_UntrustedRoot, FriendlyName)));
                        }

                        if (!settings.AllowUntrusted)
                        {
                            chainBuildingHasIssues = true;
                            flags |= SignatureVerificationStatusFlags.UntrustedRoot;
                        }
                    }

                    var offlineRevocationErrors = CertificateChainUtility.TryGetStatusAndMessage(chainStatuses, X509ChainStatusFlags.OfflineRevocation, out var _);
                    var unknownRevocationErrors = CertificateChainUtility.TryGetStatusAndMessage(chainStatuses, X509ChainStatusFlags.RevocationStatusUnknown, out var unknownRevocationStatusMessages);
                    if (offlineRevocationErrors || unknownRevocationErrors)
                    {
                        if (settings.ReportUnknownRevocation)
                        {
                            string unknownRevocationMessage = null;

                            if (unknownRevocationErrors)
                            {
                                unknownRevocationMessage = string.Format(CultureInfo.CurrentCulture, Strings.VerifyChainBuildingIssue, FriendlyName, unknownRevocationStatusMessages.First());
                            }

                            if (settings.RevocationMode == RevocationMode.Offline)
                            {
                                if (offlineRevocationErrors)
                                {
                                    issues.Add(SignatureLog.InformationLog(string.Format(CultureInfo.CurrentCulture, Strings.VerifyChainBuildingIssue, FriendlyName, Strings.VerifyCertTrustOfflineWhileRevocationModeOffline)));
                                }

                                if (unknownRevocationMessage != null)
                                {
                                    issues.Add(SignatureLog.InformationLog(unknownRevocationMessage));
                                }
                            }
                            else
                            {
                                if (offlineRevocationErrors)
                                {
                                    issues.Add(SignatureLog.Issue(!settings.AllowUnknownRevocation, NuGetLogCode.NU3018, string.Format(CultureInfo.CurrentCulture, Strings.VerifyChainBuildingIssue, FriendlyName, Strings.VerifyCertTrustOfflineWhileRevocationModeOnline)));
                                }

                                if (unknownRevocationMessage != null)
                                {
                                    issues.Add(SignatureLog.Issue(!settings.AllowUnknownRevocation, NuGetLogCode.NU3018, unknownRevocationMessage));
                                }
                            }
                        }

                        if (!settings.AllowUnknownRevocation)
                        {
                            chainBuildingHasIssues = true;
                            flags |= SignatureVerificationStatusFlags.UnknownRevocation;
                        }
                    }

                    if (!chainBuildingSucceeded)
                    {
                        // Debug log any errors
                        issues.Add(SignatureLog.DebugLog(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Strings.VerifyError_InvalidCertificateChain,
                            FriendlyName,
                            string.Join(", ", chainStatuses.Select(x => x.Status.ToString())))));
                    }

                    var isSignatureTimeValid = Rfc3161TimestampVerificationUtility.ValidateSignerCertificateAgainstTimestamp(certificate, timestamp);
                    if (isSignatureTimeValid && !chainBuildingHasIssues)
                    {
                        return new SignatureVerificationSummary(Type, SignatureVerificationStatus.Valid, flags, timestamp, issues);
                    }
                    else if (!isSignatureTimeValid)
                    {
                        issues.Add(
                            SignatureLog.Issue(
                                !settings.AllowUntrusted,
                                NuGetLogCode.NU3037,
                                string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_SignatureNotTimeValid, FriendlyName)));

                        if (!settings.AllowUntrusted)
                        {
                            flags |= SignatureVerificationStatusFlags.CertificateExpired;
                        }

                        expirationTime = DateTime.SpecifyKind(certificate.NotAfter, DateTimeKind.Local);
                    }
                }

                status = VerificationUtility.GetSignatureVerificationStatus(flags);

                return new SignatureVerificationSummary(Type, status, flags, timestamp, expirationTime, issues);
            }
        }