private static bool ShouldVerifyOwners(TrustedSignerAllowListEntry entry, IRepositorySignature repoSignature, out IReadOnlyList <string> allowedOwners, out IReadOnlyList <string> actualOwners)
        {
            allowedOwners = null;
            actualOwners  = null;

            if (entry != null && entry.Target.HasFlag(VerificationTarget.Repository) && entry.Owners != null && entry.Owners.Any() && repoSignature != null)
            {
                allowedOwners = entry.Owners ?? Enumerable.Empty <string>().ToList();
                actualOwners  = repoSignature.PackageOwners ?? Enumerable.Empty <string>().ToList();

                return(true);
            }

            return(false);
        }
        protected async override Task RunInternalAsync(ValidationContext context)
        {
            // Get the package's signature, if any.
            var signature = await GetPrimarySignatureOrNullAsync(context);

            if (signature == null)
            {
                throw new MissingRepositorySignatureException(
                          $"Package {context.Package.Id} {context.Package.Version} is unsigned",
                          MissingRepositorySignatureReason.Unsigned);
            }

            // The repository signature can be the primary signature or the author signature's countersignature.
            IRepositorySignature repositorySignature = null;

            switch (signature.Type)
            {
            case SignatureType.Repository:
                repositorySignature = (RepositoryPrimarySignature)signature;
                break;

            case SignatureType.Author:
                repositorySignature = RepositoryCountersignature.GetRepositoryCountersignature(signature);

                if (repositorySignature == null)
                {
                    throw new MissingRepositorySignatureException(
                              $"Package {context.Package.Id} {context.Package.Version} is author signed but not repository signed",
                              MissingRepositorySignatureReason.AuthorSignedNoRepositoryCountersignature);
                }

                break;

            default:
            case SignatureType.Unknown:
                throw new MissingRepositorySignatureException(
                          $"Package {context.Package.Id} {context.Package.Version} has an unknown signature type '{signature.Type}'",
                          MissingRepositorySignatureReason.UnknownSignature);
            }

            Logger.LogInformation(
                "Package {PackageId} {PackageVersion} has a repository signature with service index {ServiceIndex} and owners {Owners}",
                context.Package.Id,
                context.Package.Version,
                repositorySignature.V3ServiceIndexUrl,
                repositorySignature.PackageOwners);
        }
Example #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));
            }
        }
Example #4
0
 public RepositorySignatureInfo(Signature repositorySignature) : base(repositorySignature)
 {
     _repositorySignature = repositorySignature as IRepositorySignature ?? throw new ArgumentException("Not a repository signature", nameof(repositorySignature));
 }