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); }
/// <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)); } }
public RepositorySignatureInfo(Signature repositorySignature) : base(repositorySignature) { _repositorySignature = repositorySignature as IRepositorySignature ?? throw new ArgumentException("Not a repository signature", nameof(repositorySignature)); }