コード例 #1
0
        /// <summary>
        /// Gets certificates in the certificate chain for a timestamp on the repository countersignature.
        /// </summary>
        /// <param name="primarySignature">The primary signature.</param>
        /// <param name="repositoryCountersignature">The repository countersignature.</param>
        /// <returns>A non-empty, read-only list of X.509 certificates ordered from signing certificate to root.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="primarySignature" /> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="repositoryCountersignature" /> is <c>null</c>.</exception>
        /// <exception cref="SignatureException">Thrown if <paramref name="repositoryCountersignature" /> does not have a valid
        /// timestamp.</exception>
        /// <remarks>
        /// WARNING:  This method does not perform revocation, trust, or certificate validity checking.
        /// </remarks>
        public static IX509CertificateChain GetTimestampCertificateChain(
            PrimarySignature primarySignature,
            RepositoryCountersignature repositoryCountersignature)
        {
            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            if (repositoryCountersignature == null)
            {
                throw new ArgumentNullException(nameof(repositoryCountersignature));
            }

            if (!repositoryCountersignature.IsRelated(primarySignature))
            {
                throw new ArgumentException(Strings.UnrelatedSignatures, nameof(repositoryCountersignature));
            }

            var timestamp = repositoryCountersignature.Timestamps.FirstOrDefault();

            if (timestamp == null)
            {
                throw new SignatureException(NuGetLogCode.NU3000, Strings.RepositoryCountersignatureHasNoTimestamp);
            }

            return(GetTimestampCertificates(
                       timestamp.SignedCms,
                       SigningSpecifications.V1,
                       primarySignature.FriendlyName,
                       includeChain: true));
        }
コード例 #2
0
        public Task <PackageVerificationResult> GetTrustResultAsync(
            ISignedPackageReader package,
            PrimarySignature signature,
            SignedPackageVerifierSettings settings,
            CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }

            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            var result = Verify(signature, settings);

            return(Task.FromResult(result));
        }
コード例 #3
0
        private static async Task <bool> RemoveRepositoryCountersignaturesAsync(
            Stream input,
            Stream output,
            SignedCms signedCms,
            CancellationToken cancellationToken)
        {
            if (TryRemoveRepositoryCountersignatures(signedCms, out var updatedSignedCms))
            {
                var primarySignature = PrimarySignature.Load(updatedSignedCms.Encode());

                using (var unsignedPackage = new MemoryStream())
                {
                    using (var package = new SignedPackageArchive(input, unsignedPackage))
                    {
                        await package.RemoveSignatureAsync(cancellationToken);
                    }

                    using (var package = new SignedPackageArchive(unsignedPackage, output))
                        using (var signatureStream = new MemoryStream(primarySignature.GetBytes()))
                        {
                            await package.AddSignatureAsync(signatureStream, cancellationToken);
                        }
                }

                return(true);
            }

            return(false);
        }
コード例 #4
0
        /// <summary>
        /// Gets certificates in the certificate chain for the repository countersignature.
        /// </summary>
        /// <param name="primarySignature">The primary signature.</param>
        /// <param name="repositoryCountersignature">The repository countersignature.</param>
        /// <returns>A non-empty, read-only list of X.509 certificates ordered from signing certificate to root.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="primarySignature" /> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="repositoryCountersignature" /> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown if <paramref name="repositoryCountersignature" /> is
        /// unrelated to <paramref name="primarySignature" />.</exception>
        /// <remarks>
        /// WARNING:  This method does not perform revocation, trust, or certificate validity checking.
        /// </remarks>
        public static IX509CertificateChain GetCertificateChain(
            PrimarySignature primarySignature,
            RepositoryCountersignature repositoryCountersignature)
        {
            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            if (repositoryCountersignature == null)
            {
                throw new ArgumentNullException(nameof(repositoryCountersignature));
            }

            if (!repositoryCountersignature.IsRelated(primarySignature))
            {
                throw new ArgumentException(Strings.UnrelatedSignatures, nameof(repositoryCountersignature));
            }

            return(GetRepositoryCountersignatureCertificates(
                       primarySignature.SignedCms,
                       repositoryCountersignature.SignerInfo,
                       SigningSpecifications.V1,
                       includeChain: true));
        }
コード例 #5
0
        public static bool HasRepositoryCountersignature(PrimarySignature primarySignature)
        {
            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            if (primarySignature is RepositoryPrimarySignature)
            {
                return(false);
            }

            var counterSignatures = primarySignature.SignerInfo.CounterSignerInfos;

            foreach (var counterSignature in counterSignatures)
            {
                var countersignatureType = AttributeUtility.GetSignatureType(counterSignature.SignedAttributes);
                if (countersignatureType == SignatureType.Repository)
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #6
0
        internal bool IsRelated(PrimarySignature primarySignature)
        {
            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            return(ReferenceEquals(_primarySignature, primarySignature));
        }
コード例 #7
0
 private RepositoryCountersignature(
     PrimarySignature primarySignature,
     SignerInfo counterSignerInfo,
     Uri v3ServiceIndexUrl,
     IReadOnlyList <string> packageOwners)
     : base(counterSignerInfo, SignatureType.Repository)
 {
     _primarySignature = primarySignature;
     V3ServiceIndexUrl = v3ServiceIndexUrl;
     PackageOwners     = packageOwners;
 }
コード例 #8
0
        private PackageVerificationResult VerifySignatureAndCountersignature(
            PrimarySignature signature,
            SignedPackageVerifierSettings settings)
        {
            var issues = new List <SignatureLog>();
            var certificateExtraStore = signature.SignedCms.Certificates;
            var primarySignatureHasCountersignature = SignatureUtility.HasRepositoryCountersignature(signature);
            var status = SignatureVerificationStatus.Illegal;

            // Only accept untrusted root if the signature has a countersignature that we can validate against
            var verifySettings = new SignatureVerifySettings(
                treatIssuesAsErrors: !settings.AllowIllegal,
                allowUntrustedRoot: primarySignatureHasCountersignature,
                allowUnknownRevocation: settings.AllowUnknownRevocation,
                logOnSignatureExpired: !primarySignatureHasCountersignature);

            var primarySummary = VerifyValidityAndTrust(signature, settings, verifySettings, certificateExtraStore, issues);

            if (primarySummary != null)
            {
                status = primarySummary.Status;

                if (primarySignatureHasCountersignature)
                {
                    if (settings.AlwaysVerifyCountersignature || ShouldFallbackToRepositoryCountersignature(primarySummary))
                    {
                        var countersignature = RepositoryCountersignature.GetRepositoryCountersignature(signature);
                        verifySettings = new SignatureVerifySettings(
                            treatIssuesAsErrors: !settings.AllowIllegal,
                            allowUntrustedRoot: false,
                            allowUnknownRevocation: settings.AllowUnknownRevocation,
                            logOnSignatureExpired: true);

                        var counterSummary = VerifyValidityAndTrust(countersignature, settings, verifySettings, certificateExtraStore, issues);
                        status = counterSummary.Status;

                        if (!Rfc3161TimestampVerificationUtility.ValidateSignerCertificateAgainstTimestamp(signature.SignerInfo.Certificate, counterSummary.Timestamp))
                        {
                            issues.Add(SignatureLog.Issue(!settings.AllowIllegal, NuGetLogCode.NU3011, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_SignatureNotTimeValid, signature.FriendlyName)));
                            status = SignatureVerificationStatus.Illegal;
                        }
                    }
                    else if (primarySummary.Flags.HasFlag(SignatureVerificationStatusFlags.CertificateExpired))
                    {
                        // We are not adding this log if the primary signature has a countersignature to check the expiration against the countersignature's timestamp.
                        // If the countersignature shouldn't be check and the primary signature was expired, add this log.
                        issues.Add(SignatureLog.Issue(!settings.AllowIllegal, NuGetLogCode.NU3011, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_SignatureNotTimeValid, signature.FriendlyName)));
                    }
                }
            }

            return(new SignedPackageVerificationResult(status, signature, issues));
        }
コード例 #9
0
        /// <summary>
        /// Gets certificates in the certificate chain for the primary signature.
        /// </summary>
        /// <param name="primarySignature">The primary signature.</param>
        /// <returns>A non-empty, read-only list of X.509 certificates ordered from signing certificate to root.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="primarySignature" /> is <c>null</c>.</exception>
        /// <remarks>
        /// WARNING:  This method does not perform revocation, trust, or certificate validity checking.
        /// </remarks>
        public static IX509CertificateChain GetCertificateChain(PrimarySignature primarySignature)
        {
            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            return(GetPrimarySignatureCertificates(
                       primarySignature.SignedCms,
                       primarySignature.SignerInfo,
                       SigningSpecifications.V1,
                       includeChain: true));
        }
コード例 #10
0
        private static string GetCertificateFingerprint(
            PrimarySignature signature,
            HashAlgorithmName fingerprintAlgorithm,
            IDictionary <HashAlgorithmName, string> CertificateFingerprintLookUp)
        {
            if (!CertificateFingerprintLookUp.TryGetValue(fingerprintAlgorithm, out var fingerprintString))
            {
                var primarySignatureCertificateFingerprint = CertificateUtility.GetHash(signature.SignerInfo.Certificate, fingerprintAlgorithm);
                fingerprintString = BitConverter.ToString(primarySignatureCertificateFingerprint).Replace("-", "");
                CertificateFingerprintLookUp[fingerprintAlgorithm] = fingerprintString;
            }

            return(fingerprintString);
        }
コード例 #11
0
        private bool IsSignatureAllowed(
            PrimarySignature signature,
            IReadOnlyList <VerificationAllowListEntry> allowList)
        {
            var primarySignatureCertificateFingerprintLookUp = new Dictionary <HashAlgorithmName, string>();
            var countersignatureCertificateFingerprintLookUp = new Dictionary <HashAlgorithmName, string>();
            var repositoryCountersignature = new Lazy <RepositoryCountersignature>(() => RepositoryCountersignature.GetRepositoryCountersignature(signature));

            foreach (var allowedEntry in allowList)
            {
                // Verify the certificate hash allow list objects
                var certificateHashEntry = allowedEntry as CertificateHashAllowListEntry;
                if (certificateHashEntry != null)
                {
                    if (certificateHashEntry.Placement.HasFlag(SignaturePlacement.PrimarySignature))
                    {
                        // Get information needed for allow list verification
                        var primarySignatureCertificateFingerprint = GetCertificateFingerprint(
                            signature,
                            certificateHashEntry.FingerprintAlgorithm,
                            primarySignatureCertificateFingerprintLookUp);

                        if (IsSignatureTargeted(certificateHashEntry.Target, signature) &&
                            StringComparer.OrdinalIgnoreCase.Equals(certificateHashEntry.Fingerprint, primarySignatureCertificateFingerprint))
                        {
                            return(true);
                        }
                    }
                    if (certificateHashEntry.Placement.HasFlag(SignaturePlacement.Countersignature))
                    {
                        if (repositoryCountersignature.Value != null)
                        {
                            // Get information needed for allow list verification
                            var countersignatureCertificateFingerprint = GetCertificateFingerprint(
                                repositoryCountersignature.Value,
                                certificateHashEntry.FingerprintAlgorithm,
                                countersignatureCertificateFingerprintLookUp);

                            if (IsSignatureTargeted(certificateHashEntry.Target, repositoryCountersignature.Value) &&
                                StringComparer.OrdinalIgnoreCase.Equals(certificateHashEntry.Fingerprint, countersignatureCertificateFingerprint))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
コード例 #12
0
        private static PrimarySignature CreateRepositoryCountersignature(CmsSigner cmsSigner, PrimarySignature primarySignature, CngKey privateKey)
        {
            using (var primarySignatureNativeCms = NativeCms.Decode(primarySignature.GetBytes()))
            {
                primarySignatureNativeCms.AddCountersignature(cmsSigner, privateKey);

                var bytes      = primarySignatureNativeCms.Encode();
                var updatedCms = new SignedCms();

                updatedCms.Decode(bytes);

                return(PrimarySignature.Load(updatedCms));
            }
        }
コード例 #13
0
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public async Task <PrimarySignature> TimestampSignatureAsync(PrimarySignature primarySignature, TimestampRequest request, ILogger logger, CancellationToken token)
        {
            SignedCms timestampCms = await GetTimestampAsync(request, logger, token);

            using (ICms signatureCms = CmsFactory.Create(primarySignature.GetBytes()))
            {
                if (request.Target == SignaturePlacement.Countersignature)
                {
                    signatureCms.AddTimestampToRepositoryCountersignature(timestampCms);
                }
                else
                {
                    signatureCms.AddTimestamp(timestampCms);
                }
                return(PrimarySignature.Load(signatureCms.Encode()));
            }
        }
コード例 #14
0
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public Task <PrimarySignature> TimestampSignatureAsync(PrimarySignature primarySignature, TimestampRequest request, ILogger logger, CancellationToken token)
        {
            var timestampCms = GetTimestamp(request, logger, token);

            using (var signatureNativeCms = NativeCms.Decode(primarySignature.GetBytes()))
            {
                if (request.Target == SignaturePlacement.Countersignature)
                {
                    signatureNativeCms.AddTimestampToRepositoryCountersignature(timestampCms);
                }
                else
                {
                    signatureNativeCms.AddTimestamp(timestampCms);
                }
                return(Task.FromResult(PrimarySignature.Load(signatureNativeCms.Encode())));
            }
        }
コード例 #15
0
        /// <summary>
        /// Gets certificates in the certificate chain for a timestamp on the primary signature.
        /// </summary>
        /// <param name="signature">The primary signature.</param>
        /// <returns>A non-empty, read-only list of X.509 certificates ordered from signing certificate to root.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="signature" /> is <c>null</c>.</exception>
        /// <remarks>
        /// WARNING:  This method does not perform revocation, trust, or certificate validity checking.
        /// </remarks>
        public static IReadOnlyList <X509Certificate2> GetPrimarySignatureTimestampCertificates(
            PrimarySignature signature)
        {
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }

            var timestamp = signature.Timestamps.FirstOrDefault();

            if (timestamp == null)
            {
                throw new SignatureException(NuGetLogCode.NU3029, Strings.PrimarySignatureHasNoTimestamp);
            }

            return(GetTimestampCertificates(
                       timestamp.SignedCms,
                       SigningSpecifications.V1,
                       includeChain: true));
        }
コード例 #16
0
        /// <summary>
        /// Gets certificates in the certificate chain for a timestamp on the primary signature.
        /// </summary>
        /// <param name="primarySignature">The primary signature.</param>
        /// <returns>A non-empty, read-only list of X.509 certificates ordered from signing certificate to root.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="primarySignature" /> is <c>null</c>.</exception>
        /// <exception cref="SignatureException">Thrown if <paramref name="primarySignature" /> does not have a valid
        /// timestamp.</exception>
        /// <remarks>
        /// WARNING:  This method does not perform revocation, trust, or certificate validity checking.
        /// </remarks>
        public static IX509CertificateChain GetTimestampCertificateChain(
            PrimarySignature primarySignature)
        {
            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            var timestamp = primarySignature.Timestamps.FirstOrDefault();

            if (timestamp == null)
            {
                throw new SignatureException(NuGetLogCode.NU3000, Strings.PrimarySignatureHasNoTimestamp);
            }

            return(GetTimestampCertificates(
                       timestamp.SignedCms,
                       SigningSpecifications.V1,
                       primarySignature.FriendlyName,
                       includeChain: true));
        }
コード例 #17
0
        private static PrimarySignature CreatePrimarySignature(CmsSigner cmsSigner, SignPackageRequest request, byte[] signingData)
        {
            var contentInfo = new ContentInfo(signingData);
            var cms         = new SignedCms(contentInfo);

            try
            {
                cms.ComputeSignature(cmsSigner);
            }
            catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT)
            {
                var exceptionBuilder = new StringBuilder();

                exceptionBuilder.AppendLine(Strings.SignFailureCertificateInvalidProviderType);
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, Common.HashAlgorithmName.SHA256));

                throw new SignatureException(NuGetLogCode.NU3001, exceptionBuilder.ToString());
            }

            return(PrimarySignature.Load(cms));
        }
コード例 #18
0
        public static RepositoryCountersignature GetRepositoryCountersignature(PrimarySignature primarySignature)
        {
            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            if (primarySignature.Type == SignatureType.Repository)
            {
                throw new SignatureException(NuGetLogCode.NU3033, Strings.Error_RepositorySignatureShouldNotHaveARepositoryCountersignature);
            }

            var countersignatures = primarySignature.SignerInfo.CounterSignerInfos;
            RepositoryCountersignature repositoryCountersignature = null;

            // Only look for repository countersignatures.
            foreach (var countersignature in countersignatures)
            {
                var countersignatureType = AttributeUtility.GetSignatureType(countersignature.SignedAttributes);

                if (countersignatureType == SignatureType.Repository)
                {
                    if (repositoryCountersignature != null)
                    {
                        throw new SignatureException(NuGetLogCode.NU3032, Strings.Error_NotOneRepositoryCounterSignature);
                    }

                    var v3ServiceIndexUrl = AttributeUtility.GetNuGetV3ServiceIndexUrl(countersignature.SignedAttributes);
                    var packageOwners     = AttributeUtility.GetNuGetPackageOwners(countersignature.SignedAttributes);

                    repositoryCountersignature = new RepositoryCountersignature(
                        primarySignature,
                        countersignature,
                        v3ServiceIndexUrl,
                        packageOwners);
                }
            }

            return(repositoryCountersignature);
        }
コード例 #19
0
        private bool IsSignatureAllowed(PrimarySignature signature)
        {
            // Get information needed for allow list verification
            var primarySignatureCertificateFingerprint       = CertificateUtility.GetHash(signature.SignerInfo.Certificate, _fingerprintAlgorithm);
            var primarySignatureCertificateFingerprintString = BitConverter.ToString(primarySignatureCertificateFingerprint).Replace("-", "");

            foreach (var allowedEntry in _allowList)
            {
                // Verify the certificate hash allow list objects
                var certificateHashEntry = allowedEntry as CertificateHashAllowListEntry;
                if (certificateHashEntry != null)
                {
                    if (certificateHashEntry.VerificationTarget.HasFlag(VerificationTarget.Primary) &&
                        StringComparer.OrdinalIgnoreCase.Equals(certificateHashEntry.CertificateFingerprint, primarySignatureCertificateFingerprintString))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #20
0
        private static PrimarySignature CreateRepositoryCountersignature(CmsSigner cmsSigner, SignPackageRequest request, PrimarySignature primarySignature)
        {
            var cms = new SignedCms();

            cms.Decode(primarySignature.GetBytes());

            try
            {
                cms.SignerInfos[0].ComputeCounterSignature(cmsSigner);
            }
            catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT)
            {
                var exceptionBuilder = new StringBuilder();

                exceptionBuilder.AppendLine(Strings.SignFailureCertificateInvalidProviderType);
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, Common.HashAlgorithmName.SHA256));

                throw new SignatureException(NuGetLogCode.NU3001, exceptionBuilder.ToString());
            }

            return(PrimarySignature.Load(cms));
        }
コード例 #21
0
 public SignedPackageVerificationResult(SignatureVerificationStatus trust, PrimarySignature signature, IEnumerable <SignatureLog> issues) :
     base(trust, issues)
 {
     Signature = signature ?? throw new ArgumentNullException(nameof(signature));
 }
コード例 #22
0
        private PackageVerificationResult VerifyAllowList(ISignedPackageReader package, PrimarySignature signature, SignedPackageVerifierSettings settings)
        {
            var treatIssuesAsErrors = !settings.AllowUntrusted;
            var status = SignatureVerificationStatus.Valid;
            var issues = new List <SignatureLog>();

            if (_allowList == null || _allowList.Count == 0)
            {
                if (_requireNonEmptyAllowList)
                {
                    status = SignatureVerificationStatus.Disallowed;
                    issues.Add(SignatureLog.Error(code: NuGetLogCode.NU3034, message: _emptyListErrorMessage));
                }
            }
            else if (!IsSignatureAllowed(signature, _allowList))
            {
                if (!settings.AllowUntrusted)
                {
                    status = SignatureVerificationStatus.Disallowed;
                }

                issues.Add(SignatureLog.Issue(fatal: treatIssuesAsErrors, code: NuGetLogCode.NU3034, message: _noMatchErrorMessage));
            }

            return(new SignedPackageVerificationResult(status, signature, issues));
        }
コード例 #23
0
 public Task <PackageVerificationResult> GetTrustResultAsync(ISignedPackageReader package, PrimarySignature signature, SignedPackageVerifierSettings settings, CancellationToken token)
 {
     return(Task.FromResult(VerifyAllowList(package, signature, settings)));
 }
        private PackageVerificationResult Verify(
            PrimarySignature signature,
            SignedPackageVerifierSettings settings)
        {
            var certificateExtraStore            = signature.SignedCms.Certificates;
            var repositoryCountersignatureExists = SignatureUtility.HasRepositoryCountersignature(signature);
            var isRepositoryCountersignatureVerificationRequested = settings.VerificationTarget.HasFlag(VerificationTarget.Repository) &&
                                                                    settings.SignaturePlacement.HasFlag(SignaturePlacement.Countersignature);
            var allowDeferralToRepositoryCountersignature = isRepositoryCountersignatureVerificationRequested &&
                                                            repositoryCountersignatureExists;
            var status = SignatureVerificationStatus.Unknown;
            var issues = Enumerable.Empty <SignatureLog>();
            var isUntrustedRootAllowed = IsUntrustedRootAllowed(signature);

            var verifySettings = new SignatureVerifySettings(
                allowIllegal: settings.AllowIllegal,
                allowUntrusted: settings.AllowUntrusted || isUntrustedRootAllowed,
                allowUnknownRevocation: settings.AllowUnknownRevocation,
                reportUnknownRevocation: settings.ReportUnknownRevocation,
                reportUntrustedRoot: !isUntrustedRootAllowed,
                revocationMode: settings.RevocationMode);

            SignatureVerificationSummary primarySummary = null;

            if (settings.SignaturePlacement.HasFlag(SignaturePlacement.PrimarySignature) &&
                VerificationUtility.IsVerificationTarget(signature.Type, settings.VerificationTarget))
            {
                primarySummary = VerifyValidityAndTrust(signature, settings, verifySettings, certificateExtraStore);

                issues = issues.Concat(primarySummary.Issues);

                status = primarySummary.Status;
            }

            Debug.Assert(isRepositoryCountersignatureVerificationRequested != (settings.RepositoryCountersignatureVerificationBehavior == SignatureVerificationBehavior.Never));

            bool shouldVerifyRepositoryCountersignature;

            switch (settings.RepositoryCountersignatureVerificationBehavior)
            {
            case SignatureVerificationBehavior.IfExists:
                shouldVerifyRepositoryCountersignature = isRepositoryCountersignatureVerificationRequested &&
                                                         repositoryCountersignatureExists;
                break;

            case SignatureVerificationBehavior.IfExistsAndIsNecessary:
                // The repository countersignature should be evaluated if settings allow it, if a repository countersignature exists
                // and if either settings only allow a repository countersignature to be evaluated or the primary signature has some
                // validation/trust issues that may benefit from a repository countersignature fallback.
                shouldVerifyRepositoryCountersignature = isRepositoryCountersignatureVerificationRequested &&
                                                         repositoryCountersignatureExists &&
                                                         (primarySummary == null ||
                                                          (primarySummary != null &&
                                                           (HasUntrustedRoot(primarySummary) || IsSignatureExpired(primarySummary))));
                break;

            case SignatureVerificationBehavior.Always:
                shouldVerifyRepositoryCountersignature = isRepositoryCountersignatureVerificationRequested;
                break;

            case SignatureVerificationBehavior.Never:
                shouldVerifyRepositoryCountersignature = false;
                break;

            default:
                throw new NotImplementedException();
            }

            if (shouldVerifyRepositoryCountersignature)
            {
                var countersignature = RepositoryCountersignature.GetRepositoryCountersignature(signature);

                if (countersignature == null)
                {
                    if (settings.RepositoryCountersignatureVerificationBehavior == SignatureVerificationBehavior.Always)
                    {
                        issues = issues.Concat(new[] { SignatureLog.Error(NuGetLogCode.NU3038, Strings.NoRepositoryCountersignature) });
                        status = SignatureVerificationStatus.Disallowed;
                    }
                }
                else
                {
                    isUntrustedRootAllowed = IsUntrustedRootAllowed(countersignature);

                    verifySettings = new SignatureVerifySettings(
                        allowIllegal: settings.AllowIllegal,
                        allowUntrusted: settings.AllowUntrusted || isUntrustedRootAllowed,
                        allowUnknownRevocation: settings.AllowUnknownRevocation,
                        reportUnknownRevocation: settings.ReportUnknownRevocation,
                        reportUntrustedRoot: !isUntrustedRootAllowed,
                        revocationMode: settings.RevocationMode);

                    var countersignatureSummary = VerifyValidityAndTrust(countersignature, settings, verifySettings, certificateExtraStore);

                    if (primarySummary == null)
                    {
                        status = countersignatureSummary.Status;
                    }
                    else
                    {
                        if (countersignatureSummary.Status == SignatureVerificationStatus.Valid)
                        {
                            if (IsSignatureExpired(primarySummary) && HasUntrustedRoot(primarySummary))
                            {
                                // Exclude the issue of the primary signature being untrusted since the repository countersignature fulfills the role of a trust anchor.
                                issues = issues.Where(log => log.Code != NuGetLogCode.NU3018);

                                if (countersignatureSummary.Timestamp != null &&
                                    Rfc3161TimestampVerificationUtility.ValidateSignerCertificateAgainstTimestamp(signature.SignerInfo.Certificate, countersignatureSummary.Timestamp))
                                {
                                    // Exclude the issue of the primary signature being expired since the repository countersignature fulfills the role of a trusted timestamp.
                                    issues = issues.Where(log => log.Code != NuGetLogCode.NU3037);

                                    status = SignatureVerificationStatus.Valid;
                                }
                            }
                            else if (IsSignatureExpired(primarySummary) &&
                                     countersignatureSummary.Timestamp != null &&
                                     Rfc3161TimestampVerificationUtility.ValidateSignerCertificateAgainstTimestamp(signature.SignerInfo.Certificate, countersignatureSummary.Timestamp))
                            {
                                // Exclude the issue of the primary signature being expired since the repository countersignature fulfills the role of a trusted timestamp.
                                issues = issues.Where(log => log.Code != NuGetLogCode.NU3037);

                                status = SignatureVerificationStatus.Valid;
                            }
                            else if (HasUntrustedRoot(primarySummary))
                            {
                                // Exclude the issue of the primary signature being untrusted since the repository countersignature fulfills the role of a trust anchor.
                                issues = issues.Where(log => log.Code != NuGetLogCode.NU3018);

                                status = SignatureVerificationStatus.Valid;
                            }
                        }

                        // Both the primary signature and the repository countersignature were evaluated.
                        // The overall status should be the more severe status of the two.
                        status = (SignatureVerificationStatus)Math.Min((int)status, (int)countersignatureSummary.Status);
                    }

                    issues = issues.Concat(countersignatureSummary.Issues);
                }
            }

            return(new SignedPackageVerificationResult(status, signature, issues));
        }
 private PackageVerificationResult Verify(
     PrimarySignature signature,
     SignedPackageVerifierSettings settings)
 {
     throw new NotSupportedException();
 }
コード例 #26
0
        public Task <PackageVerificationResult> GetTrustResultAsync(ISignedPackageReader package, PrimarySignature signature, SignedPackageVerifierSettings settings, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            var result = VerifyValidityAndTrust(signature, settings);

            return(Task.FromResult(result));
        }
コード例 #27
0
 /// <summary>
 /// Timestamp a signature.
 /// </summary>
 public Task <PrimarySignature> TimestampSignatureAsync(PrimarySignature primarySignature, TimestampRequest timestampRequest, ILogger logger, CancellationToken token)
 {
     throw new NotImplementedException();
 }
コード例 #28
0
 private PackageVerificationResult VerifyAllowList(ISignedPackageReader package, PrimarySignature signature, SignedPackageVerifierSettings settings)
 {
     throw new NotSupportedException();
 }
コード例 #29
0
        /// <summary>
        /// Countersign the primary signature with a X509Certificate2.
        /// </summary>
        public Task <PrimarySignature> CreateRepositoryCountersignatureAsync(RepositorySignPackageRequest request, PrimarySignature primarySignature, ILogger logger, CancellationToken token)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (primarySignature == null)
            {
                throw new ArgumentNullException(nameof(primarySignature));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            token.ThrowIfCancellationRequested();

            var signature = CreateRepositoryCountersignature(request, primarySignature, logger);

            if (_timestampProvider == null)
            {
                return(Task.FromResult(signature));
            }
            else
            {
                return(TimestampRepositoryCountersignatureAsync(request, logger, signature, token));
            }
        }
コード例 #30
0
 private Task <PrimarySignature> TimestampRepositoryCountersignatureAsync(SignPackageRequest request, ILogger logger, PrimarySignature signature, CancellationToken token)
 {
     throw new NotSupportedException();
 }