Task <SignatureVerificationStatus> VerifyAsync(
            ISignedPackageReader reader,
            CancellationToken cancellationToken)
        {
#if IS_DESKTOP
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (!await reader.IsSignedAsync(cancellationToken))
            {
                throw new SignatureException(Strings.SignedPackageNotSignedOnVerify);
            }

            var primarySignature = await reader.GetPrimarySignatureAsync(cancellationToken);

            var integrityVerificationProvider = new IntegrityVerificationProvider();

            var result = await integrityVerificationProvider.GetTrustResultAsync(
                reader,
                primarySignature,
                _settings,
                cancellationToken);

            if (result.Trust != SignatureVerificationStatus.Valid)
            {
                return(result.Trust);
            }

            if (primarySignature is RepositoryPrimarySignature)
            {
                return(VerifyRepositorySignature(primarySignature, primarySignature.SignedCms.Certificates));
            }

            var countersignature = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature);

            if (countersignature == null)
            {
                throw new SignatureException(Strings.NoRepositorySignature);
            }

            return(VerifyRepositorySignature(countersignature, primarySignature.SignedCms.Certificates));
#else
            throw new NotImplementedException();
#endif
        }
Esempio n. 2
0
        public async Task <VerifySignaturesResult> VerifySignaturesAsync(ISignedPackageReader package, SignedPackageVerifierSettings settings, CancellationToken token, Guid parentId = default(Guid))
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

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

            var valid        = false;
            var trustResults = new List <PackageVerificationResult>();

            var packageSigningTelemetryEvent = new PackageSigningTelemetryEvent();

            using (var telemetry = TelemetryActivity.Create(parentId, packageSigningTelemetryEvent))
            {
                var isSigned = await package.IsSignedAsync(token);

                if (isSigned)
                {
                    try
                    {
                        var signature = await package.GetPrimarySignatureAsync(token);

                        if (signature != null)
                        {
                            // Verify that the signature is trusted
                            var sigTrustResults = await Task.WhenAll(_verificationProviders.Select(e => e.GetTrustResultAsync(package, signature, settings, token)));

                            valid = IsValid(sigTrustResults);
                            trustResults.AddRange(sigTrustResults);
                        }
                        else
                        {
                            valid = false;
                        }
                    }
                    catch (SignatureException e)
                    {
                        // SignatureException generated while parsing signatures
                        var issues = new[] {
                            SignatureLog.Issue(!settings.AllowIllegal, e.Code, e.Message),
                            SignatureLog.DebugLog(e.ToString())
                        };
                        trustResults.Add(new InvalidSignaturePackageVerificationResult(
                                             settings.AllowIllegal ? SignatureVerificationStatus.Valid : SignatureVerificationStatus.Disallowed,
                                             issues));
                        valid = settings.AllowIllegal;
                    }
                    catch (CryptographicException e)
                    {
                        // CryptographicException generated while parsing the SignedCms object
                        var issues = new[] {
                            SignatureLog.Issue(!settings.AllowIllegal, NuGetLogCode.NU3003, Strings.ErrorPackageSignatureInvalid),
                            SignatureLog.DebugLog(e.ToString())
                        };
                        trustResults.Add(new InvalidSignaturePackageVerificationResult(
                                             settings.AllowIllegal ? SignatureVerificationStatus.Valid : SignatureVerificationStatus.Disallowed,
                                             issues));
                        valid = settings.AllowIllegal;
                    }
                }
                else if (settings.AllowUnsigned)
                {
                    // An unsigned package is valid only if unsigned packages are allowed.
                    valid = true;
                }
                else
                {
                    var issues = new[] { SignatureLog.Issue(fatal: true, code: NuGetLogCode.NU3004, message: Strings.ErrorPackageNotSigned) };
                    trustResults.Add(new UnsignedPackageVerificationResult(
                                         settings.AllowIllegal ? SignatureVerificationStatus.Valid : SignatureVerificationStatus.Disallowed,
                                         issues));
                    valid = false;
                }

                var status = valid ? NuGetOperationStatus.Succeeded : NuGetOperationStatus.Failed;
                packageSigningTelemetryEvent.SetResult(isSigned ? PackageSignType.Signed : PackageSignType.Unsigned, status);

                return(new VerifySignaturesResult(valid, isSigned, trustResults));
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Adds a trusted signer item to the settings based a signed package.
        /// </summary>
        /// <param name="name">Name of the trusted signer.</param>
        /// <param name="package">Package to read signature from.</param>
        /// <param name="trustTarget">Signature to trust from package.</param>
        /// <param name="allowUntrustedRoot">Specifies if allowUntrustedRoot should be set to true.</param>
        /// <param name="owners">Trusted owners that should be set when trusting a repository.</param>
        /// <param name="token">Cancellation token for async request</param>
        public async Task AddTrustedSignerAsync(string name, ISignedPackageReader package, VerificationTarget trustTarget, bool allowUntrustedRoot, IEnumerable <string> owners, CancellationToken token)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException(Strings.ArgumentCannotBeNullOrEmpty, nameof(name));
            }

            if (!Enum.IsDefined(typeof(VerificationTarget), trustTarget) || (trustTarget != VerificationTarget.Repository && trustTarget != VerificationTarget.Author))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_UnsupportedTrustTarget, trustTarget.ToString()));
            }

            if (trustTarget == VerificationTarget.Author && owners != null && owners.Any())
            {
                throw new ArgumentException(Strings.Error_TrustedAuthorNoOwners);
            }

            token.ThrowIfCancellationRequested();

            string v3ServiceIndex = null;
            IRepositorySignature repositorySignature = null;
            var trustingRepository = trustTarget.HasFlag(VerificationTarget.Repository);

            var primarySignature = await package.GetPrimarySignatureAsync(token);

            if (primarySignature == null)
            {
                throw new InvalidOperationException(Strings.Error_PackageNotSigned);
            }

            if (trustingRepository)
            {
                if (primarySignature.Type == SignatureType.Repository)
                {
                    repositorySignature = primarySignature as RepositoryPrimarySignature;
                }
                else
                {
                    var countersignature = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature);
                    repositorySignature = countersignature ?? throw new InvalidOperationException(Strings.Error_RepoTrustExpectedRepoSignature);
                }

                v3ServiceIndex = repositorySignature.V3ServiceIndexUrl.AbsoluteUri;
            }

            ValidateNoExistingSigner(name, v3ServiceIndex, trustingRepository);

            if (trustingRepository)
            {
                var certificateItem = GetCertificateItemForSignature(repositorySignature, allowUntrustedRoot);

                _trustedSignersProvider.AddOrUpdateTrustedSigner(new RepositoryItem(name, v3ServiceIndex, CreateOwnersList(owners), certificateItem));

                await _logger.LogAsync(LogLevel.Information, string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullyAddedTrustedRepository, name));
            }
            else
            {
                if (primarySignature.Type != SignatureType.Author)
                {
                    throw new InvalidOperationException(Strings.Error_AuthorTrustExpectedAuthorSignature);
                }

                var certificateItem = GetCertificateItemForSignature(primarySignature, allowUntrustedRoot);

                _trustedSignersProvider.AddOrUpdateTrustedSigner(new AuthorItem(name, certificateItem));

                await _logger.LogAsync(LogLevel.Information, string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullyAddedTrustedAuthor, name));
            }
        }