public CertificateEntryLookupEntry(VerificationTarget target, SignaturePlacement placement, CertificateItem certificate, ICollection <string> owners = null)
 {
     Target      = target;
     Placement   = placement;
     Certificate = certificate ?? throw new ArgumentNullException(nameof(certificate));
     Owners      = owners;
 }
Exemplo n.º 2
0
        protected SignPackageRequest(
            X509Certificate2 certificate,
            HashAlgorithmName signatureHashAlgorithm,
            HashAlgorithmName timestampHashAlgorithm,
            SignaturePlacement signaturePlacement)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            if (!Enum.IsDefined(typeof(HashAlgorithmName), signatureHashAlgorithm) ||
                signatureHashAlgorithm == HashAlgorithmName.Unknown)
            {
                throw new ArgumentException(Strings.InvalidArgument, nameof(signatureHashAlgorithm));
            }

            if (!Enum.IsDefined(typeof(HashAlgorithmName), timestampHashAlgorithm) ||
                timestampHashAlgorithm == HashAlgorithmName.Unknown)
            {
                throw new ArgumentException(Strings.InvalidArgument, nameof(timestampHashAlgorithm));
            }

            if (!Enum.IsDefined(typeof(SignaturePlacement), signaturePlacement))
            {
                throw new ArgumentException(Strings.InvalidArgument, nameof(signaturePlacement));
            }

            Certificate            = certificate;
            SignatureHashAlgorithm = signatureHashAlgorithm;
            TimestampHashAlgorithm = timestampHashAlgorithm;
            SignaturePlacement     = signaturePlacement;
            AdditionalCertificates = new X509Certificate2Collection();
        }
Exemplo n.º 3
0
        public void Constructor_InitializesProperties(
            bool boolValue,
            VerificationTarget verificationTarget,
            SignaturePlacement signaturePlacement,
            SignatureVerificationBehavior signatureVerificationBehavior,
            RevocationMode revocationMode)
        {
            // Arrange & Act
            var settings = new SignedPackageVerifierSettings(
                allowUnsigned: boolValue,
                allowIllegal: boolValue,
                allowUntrusted: boolValue,
                allowIgnoreTimestamp: boolValue,
                allowMultipleTimestamps: boolValue,
                allowNoTimestamp: boolValue,
                allowUnknownRevocation: boolValue,
                reportUnknownRevocation: boolValue,
                verificationTarget: verificationTarget,
                signaturePlacement: signaturePlacement,
                repositoryCountersignatureVerificationBehavior: signatureVerificationBehavior,
                revocationMode: revocationMode);

            // Assert
            settings.AllowUnsigned.Should().Be(boolValue);
            settings.AllowIllegal.Should().Be(boolValue);
            settings.AllowUntrusted.Should().Be(boolValue);
            settings.AllowIgnoreTimestamp.Should().Be(boolValue);
            settings.AllowMultipleTimestamps.Should().Be(boolValue);
            settings.AllowNoTimestamp.Should().Be(boolValue);
            settings.AllowUnknownRevocation.Should().Be(boolValue);
            settings.ReportUnknownRevocation.Should().Be(boolValue);
            settings.RepositoryCountersignatureVerificationBehavior.Should().Be(signatureVerificationBehavior);
            settings.RevocationMode.Should().Be(revocationMode);
        }
Exemplo n.º 4
0
 public TimestampRequest(SigningSpecifications signingSpecifications, byte[] hashedMessage, HashAlgorithmName hashAlgorithm, SignaturePlacement target)
 {
     SigningSpecifications = signingSpecifications ?? throw new ArgumentNullException(nameof(signingSpecifications));
     HashedMessage         = hashedMessage ?? throw new ArgumentNullException(nameof(hashedMessage));
     HashAlgorithm         = hashAlgorithm;
     Target = target;
 }
        public void ConstructorWithLists_WhenArgumentCombinationIsInvalid_Throws(
            VerificationTarget verificationTarget,
            SignaturePlacement signaturePlacement,
            SignatureVerificationBehavior repositoryCountersignatureVerificationBehavior,
            string parameterName1,
            string parameterName2)
        {
            var exception = Assert.Throws <ArgumentException>(() => new SignedPackageVerifierSettings(
                                                                  allowUnsigned: false,
                                                                  allowIllegal: false,
                                                                  allowUntrusted: false,
                                                                  allowIgnoreTimestamp: false,
                                                                  allowMultipleTimestamps: false,
                                                                  allowNoTimestamp: false,
                                                                  allowUnknownRevocation: false,
                                                                  reportUnknownRevocation: true,
                                                                  verificationTarget: verificationTarget,
                                                                  signaturePlacement: signaturePlacement,
                                                                  repositoryCountersignatureVerificationBehavior: repositoryCountersignatureVerificationBehavior,
                                                                  allowNoRepositoryCertificateList: false,
                                                                  allowNoClientCertificateList: false,
                                                                  repoAllowListEntries: Array.Empty <VerificationAllowListEntry>(),
                                                                  clientAllowListEntries: Array.Empty <VerificationAllowListEntry>()));

            Assert.Equal(parameterName2, exception.ParamName);
            Assert.StartsWith($"Invalid combination of arguments {parameterName1} and {parameterName2}.", exception.Message);
        }
 public SignedPackageVerifierSettings(
     bool allowUnsigned,
     bool allowIllegal,
     bool allowUntrusted,
     bool allowIgnoreTimestamp,
     bool allowMultipleTimestamps,
     bool allowNoTimestamp,
     bool allowUnknownRevocation,
     bool reportUnknownRevocation,
     bool allowNoRepositoryCertificateList,
     bool allowNoClientCertificateList,
     VerificationTarget verificationTarget,
     SignaturePlacement signaturePlacement,
     SignatureVerificationBehavior repositoryCountersignatureVerificationBehavior,
     RevocationMode revocationMode)
     : this(
         allowUnsigned,
         allowIllegal,
         allowUntrusted,
         allowIgnoreTimestamp,
         allowMultipleTimestamps,
         allowNoTimestamp,
         allowUnknownRevocation,
         reportUnknownRevocation,
         allowNoRepositoryCertificateList,
         allowNoClientCertificateList,
         verificationTarget,
         signaturePlacement,
         repositoryCountersignatureVerificationBehavior,
         revocationMode,
         repoAllowListEntries : null,
         clientAllowListEntries : null)
 {
 }
        public VerificationAllowListEntry(VerificationTarget target, SignaturePlacement placement)
        {
            if (target == VerificationTarget.Author && placement.HasFlag(SignaturePlacement.Countersignature))
            {
                throw new ArgumentException(Strings.ErrorAuthorTargetCannotBeACountersignature);
            }

            Target    = target;
            Placement = placement;
        }
        private static VerificationTarget GetItemTarget(TrustedSignerItem item, out SignaturePlacement placement)
        {
            if (item is RepositoryItem)
            {
                placement = SignaturePlacement.Any;
                return(VerificationTarget.Repository);
            }

            placement = SignaturePlacement.PrimarySignature;
            return(VerificationTarget.Author);
        }
Exemplo n.º 9
0
 public TrustedSignerAllowListEntry(
     VerificationTarget target,
     SignaturePlacement placement,
     string fingerprint,
     HashAlgorithmName algorithm,
     bool allowUntrustedRoot       = false,
     IReadOnlyList <string> owners = null)
     : base(target, placement, fingerprint, algorithm)
 {
     AllowUntrustedRoot = allowUntrustedRoot;
     Owners             = owners;
 }
Exemplo n.º 10
0
        private static void AddCertificateFingerprintIntoAllowList(
            VerificationTarget target,
            SignaturePlacement placement,
            HashAlgorithmName algorithm,
            IRepositoryCertificateInfo certInfo,
            List <CertificateHashAllowListEntry> allowList)
        {
            var fingerprint = certInfo.Fingerprints[algorithm.ConvertToOidString()];

            if (!string.IsNullOrEmpty(fingerprint))
            {
                allowList.Add(new CertificateHashAllowListEntry(target, placement, fingerprint, algorithm));
            }
        }
        public void ConstructorWithLists_InitializesProperties(
            bool boolValue,
            VerificationTarget verificationTarget,
            SignaturePlacement signaturePlacement,
            SignatureVerificationBehavior signatureVerificationBehavior,
            RevocationMode revocationMode)
        {
            // Arrange
            var repoList   = new List <CertificateHashAllowListEntry>();
            var clientList = new List <CertificateHashAllowListEntry>();

            // Act
            var settings = new SignedPackageVerifierSettings(
                allowUnsigned: boolValue,
                allowIllegal: boolValue,
                allowUntrusted: boolValue,
                allowIgnoreTimestamp: boolValue,
                allowMultipleTimestamps: boolValue,
                allowNoTimestamp: boolValue,
                allowUnknownRevocation: boolValue,
                reportUnknownRevocation: boolValue,
                allowNoRepositoryCertificateList: boolValue,
                allowNoClientCertificateList: boolValue,
                verificationTarget: verificationTarget,
                signaturePlacement: signaturePlacement,
                repositoryCountersignatureVerificationBehavior: signatureVerificationBehavior,
                revocationMode: revocationMode,
                repoAllowListEntries: repoList,
                clientAllowListEntries: clientList);

            // Assert
            settings.AllowUnsigned.Should().Be(boolValue);
            settings.AllowIllegal.Should().Be(boolValue);
            settings.AllowUntrusted.Should().Be(boolValue);
            settings.AllowIgnoreTimestamp.Should().Be(boolValue);
            settings.AllowMultipleTimestamps.Should().Be(boolValue);
            settings.AllowNoTimestamp.Should().Be(boolValue);
            settings.AllowUnknownRevocation.Should().Be(boolValue);
            settings.AllowNoRepositoryCertificateList.Should().Be(boolValue);
            settings.AllowNoClientCertificateList.Should().Be(boolValue);
            settings.RepositoryCountersignatureVerificationBehavior.Should().Be(signatureVerificationBehavior);
            settings.RevocationMode.Should().Be(revocationMode);
            settings.RepositoryCertificateList.Should().BeSameAs(repoList);
            settings.ClientCertificateList.Should().BeSameAs(clientList);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Instantiates a new instance of the <see cref="RepositorySignPackageRequest" /> class.
        /// </summary>
        /// <param name="certificate">The signing certificate.</param>
        /// <param name="signatureHashAlgorithm">The signature hash algorithm.</param>
        /// <param name="timestampHashAlgorithm">The timestamp hash algorithm.</param>
        /// <param name="signaturePlacement">The signature placement.</param>
        /// <param name="v3ServiceIndexUrl">The V3 service index URL.</param>
        /// <param name="packageOwners">A read-only list of package owners.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="certificate" />
        /// is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown if <paramref name="signatureHashAlgorithm" />
        /// is invalid.</exception>
        /// <exception cref="ArgumentException">Thrown if <paramref name="timestampHashAlgorithm" />
        /// is invalid.</exception>
        /// <exception cref="ArgumentException">Thrown if <paramref name="signaturePlacement" />
        /// is invalid.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="v3ServiceIndexUrl" />
        /// is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown if <paramref name="v3ServiceIndexUrl" />
        /// is neither absolute nor HTTPS.</exception>
        /// <exception cref="ArgumentException">Thrown if <paramref name="packageOwners" />
        /// is either empty or contains an invalid value.</exception>
        public RepositorySignPackageRequest(
            X509Certificate2 certificate,
            HashAlgorithmName signatureHashAlgorithm,
            HashAlgorithmName timestampHashAlgorithm,
            SignaturePlacement signaturePlacement,
            Uri v3ServiceIndexUrl,
            IReadOnlyList <string> packageOwners)
            : base(
                certificate,
                signatureHashAlgorithm,
                timestampHashAlgorithm,
                signaturePlacement)
        {
            if (v3ServiceIndexUrl == null)
            {
                throw new ArgumentNullException(nameof(v3ServiceIndexUrl));
            }

            if (!v3ServiceIndexUrl.IsAbsoluteUri)
            {
                throw new ArgumentException(Strings.InvalidUrl, nameof(v3ServiceIndexUrl));
            }

            if (!string.Equals(v3ServiceIndexUrl.Scheme, "https", StringComparison.Ordinal))
            {
                throw new ArgumentException(Strings.InvalidUrl, nameof(v3ServiceIndexUrl));
            }

            if (packageOwners != null)
            {
                if (packageOwners.Any(packageOwner => string.IsNullOrWhiteSpace(packageOwner)))
                {
                    throw new ArgumentException(Strings.NuGetPackageOwnersInvalidValue, nameof(packageOwners));
                }

                if (!packageOwners.Any())
                {
                    packageOwners = null;
                }
            }

            V3ServiceIndexUrl = v3ServiceIndexUrl;
            PackageOwners     = packageOwners;
        }
        public CertificateHashAllowListEntry(VerificationTarget target, SignaturePlacement placement, string fingerprint, HashAlgorithmName algorithm)
            : base(target, placement)
        {
            if (!Enum.IsDefined(typeof(SignaturePlacement), placement))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.UnrecognizedEnumValue,
                              placement),
                          nameof(placement));
            }

            if (!Enum.IsDefined(typeof(HashAlgorithmName), algorithm))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.UnrecognizedEnumValue,
                              algorithm),
                          nameof(algorithm));
            }

            if ((placement.HasFlag(SignaturePlacement.Countersignature) && !target.HasFlag(VerificationTarget.Repository)) ||
                (placement == SignaturePlacement.Countersignature && target != VerificationTarget.Repository))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.InvalidArgumentCombination,
                              nameof(target),
                              nameof(placement)),
                          nameof(placement));
            }

            Fingerprint          = fingerprint ?? throw new ArgumentNullException(nameof(fingerprint));
            FingerprintAlgorithm = algorithm;
        }
Exemplo n.º 14
0
        public static Task <PrimarySignature> TimestampSignature(ITimestampProvider timestampProvider, PrimarySignature primarySignature, HashAlgorithmName hashAlgorithm, SignaturePlacement target, ILogger logger)
        {
            Signature signatureToTimestamp = primarySignature;

            if (target == SignaturePlacement.Countersignature)
            {
                signatureToTimestamp = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature);
            }

            var signatureValue = signatureToTimestamp.GetSignatureValue();
            var messageHash    = hashAlgorithm.ComputeHash(signatureValue);

            var timestampRequest = new TimestampRequest(
                SigningSpecifications.V1,
                messageHash,
                hashAlgorithm,
                target);

            return(timestampProvider.TimestampSignatureAsync(primarySignature, timestampRequest, logger, CancellationToken.None));
        }
 public CertificateHashAllowListEntry(VerificationTarget target, SignaturePlacement placement, string fingerprint, HashAlgorithmName algorithm)
     : base(target, placement)
 {
     Fingerprint          = fingerprint;
     FingerprintAlgorithm = algorithm;
 }
        public SignedPackageVerifierSettings(
            bool allowUnsigned,
            bool allowIllegal,
            bool allowUntrusted,
            bool allowIgnoreTimestamp,
            bool allowMultipleTimestamps,
            bool allowNoTimestamp,
            bool allowUnknownRevocation,
            bool reportUnknownRevocation,
            VerificationTarget verificationTarget,
            SignaturePlacement signaturePlacement,
            SignatureVerificationBehavior repositoryCountersignatureVerificationBehavior,
            RevocationMode revocationMode)
        {
            if (!Enum.IsDefined(typeof(VerificationTarget), verificationTarget))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.UnrecognizedEnumValue,
                              verificationTarget),
                          nameof(verificationTarget));
            }

            if (!Enum.IsDefined(typeof(SignaturePlacement), signaturePlacement))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.UnrecognizedEnumValue,
                              signaturePlacement),
                          nameof(signaturePlacement));
            }

            if (!Enum.IsDefined(typeof(SignatureVerificationBehavior), repositoryCountersignatureVerificationBehavior))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.UnrecognizedEnumValue,
                              repositoryCountersignatureVerificationBehavior),
                          nameof(repositoryCountersignatureVerificationBehavior));
            }

            if ((signaturePlacement.HasFlag(SignaturePlacement.Countersignature) && !verificationTarget.HasFlag(VerificationTarget.Repository)) ||
                (signaturePlacement == SignaturePlacement.Countersignature && verificationTarget != VerificationTarget.Repository))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.InvalidArgumentCombination,
                              nameof(verificationTarget),
                              nameof(signaturePlacement)),
                          nameof(signaturePlacement));
            }

            if ((repositoryCountersignatureVerificationBehavior == SignatureVerificationBehavior.Never) ==
                signaturePlacement.HasFlag(SignaturePlacement.Countersignature) ||
                ((repositoryCountersignatureVerificationBehavior == SignatureVerificationBehavior.Always) &&
                 !signaturePlacement.HasFlag(SignaturePlacement.Countersignature)))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.InvalidArgumentCombination,
                              nameof(signaturePlacement),
                              nameof(repositoryCountersignatureVerificationBehavior)),
                          nameof(repositoryCountersignatureVerificationBehavior));
            }

            AllowUnsigned           = allowUnsigned;
            AllowIllegal            = allowIllegal;
            AllowUntrusted          = allowUntrusted;
            AllowIgnoreTimestamp    = allowIgnoreTimestamp;
            AllowMultipleTimestamps = allowMultipleTimestamps;
            AllowNoTimestamp        = allowNoTimestamp;
            AllowUnknownRevocation  = allowUnknownRevocation;
            ReportUnknownRevocation = reportUnknownRevocation;
            VerificationTarget      = verificationTarget;
            SignaturePlacement      = signaturePlacement;
            RepositoryCountersignatureVerificationBehavior = repositoryCountersignatureVerificationBehavior;
            RevocationMode = revocationMode;
        }
Exemplo n.º 17
0
        public async Task ClientPolicies_WithSignerInTrustedSignersListAsync(SigningTestType signature, SignaturePlacement trustedSigner, string validationMode)
        {
            // Arrange
            using (var dir = TestDirectory.Create())
                using (var authorCertificate = new X509Certificate2(_trustedAuthorTestCert.Source.Cert))
                    using (var repoCertificate = new X509Certificate2(_trustedRepoTestCert.Source.Cert))
                    {
                        var authorCertificateFingerprintString = SignatureTestUtility.GetFingerprint(authorCertificate, HashAlgorithmName.SHA256);
                        var repoCertificateFingerprintString   = SignatureTestUtility.GetFingerprint(repoCertificate, HashAlgorithmName.SHA256);

                        var signedPackagePath = await CreateSignedPackageAsync(dir, signature, authorCertificate, repoCertificate);

                        var trustedSignerString = "";

                        if (signature == SigningTestType.Author || (signature == SigningTestType.RepositoryCountersigned && trustedSigner == SignaturePlacement.PrimarySignature))
                        {
                            trustedSignerString = $@"<author name=""author1""><certificate fingerprint=""{authorCertificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" /></author>";
                        }
                        else
                        {
                            trustedSignerString = $@"<repository name=""repo1"" serviceIndex=""https://api.v3serviceIndex.test/json""><certificate fingerprint=""{repoCertificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" /></repository>";
                        }

                        var config = $@"
<configuration>
    <config>
        <add key=""signatureValidationMode"" value=""{validationMode}"" />
    </config>
    <trustedSigners>
        {trustedSignerString}
    </trustedSigners>
</configuration>";

                        var nugetConfigPath = "NuGet.Config";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, dir, config);

                        // Act and Assert
                        var settings = new Settings(dir);

                        var verifierSettings = SignedPackageVerifierSettings.GetClientPolicy(settings, NullLogger.Instance);
                        var trustProviders   = new[]
                        {
                            new AllowListVerificationProvider()
                        };
                        var verifier = new PackageSignatureVerifier(trustProviders);

                        using (var packageReader = new PackageArchiveReader(signedPackagePath))
                        {
                            // Act
                            var result = await verifier.VerifySignaturesAsync(packageReader, verifierSettings, CancellationToken.None);

                            var resultsWithWarnings = result.Results.Where(r => r.GetWarningIssues().Any());
                            var resultsWithErrors   = result.Results.Where(r => r.GetErrorIssues().Any());
                            var totalWarningIssues  = resultsWithWarnings.SelectMany(r => r.GetWarningIssues());
                            var totalErrorIssues    = resultsWithErrors.SelectMany(r => r.GetErrorIssues());

                            // Assert
                            result.Valid.Should().BeTrue();
                            totalWarningIssues.Count().Should().Be(0);
                            totalErrorIssues.Count().Should().Be(0);
                        }
                    }
        }