/// <summary>
        /// Generates an repository signed copy of a package and returns the path to that package
        /// This method can timestamp a package and should only be used with tests marked with [CIOnlyFact]
        /// </summary>
        /// <param name="certificate">Certificate to be used while signing the package</param>
        /// <param name="nupkg">Package to be signed</param>
        /// <param name="dir">Directory for placing the signed package</param>
        /// <param name="timestampService">RFC 3161 timestamp service URL.</param>
        /// <param name="v3ServiceIndex">Value for the V3ServiceIndex for the repository signature attribute</param>
        /// <param name="packageOwners">List of package owners for teh repository signature attribute</param>
        /// <param name="signatureHashAlgorithm">Hash algorithm to be used in the signature. Defaults to SHA256</param>
        /// <param name="timestampHashAlgorithm">Hash algorithm to be used in the timestamp. Defaults to SHA256</param>
        /// <returns>Path to the signed copy of the package</returns>
        public static async Task <string> RepositorySignPackageAsync(
            X509Certificate2 certificate,
            SimpleTestPackageContext nupkg,
            string dir,
            Uri v3ServiceIndex,
            Uri timestampService = null,
            IReadOnlyList <string> packageOwners     = null,
            HashAlgorithmName signatureHashAlgorithm = HashAlgorithmName.SHA256,
            HashAlgorithmName timestampHashAlgorithm = HashAlgorithmName.SHA256)
        {
            var signedPackagePath = Path.Combine(dir, $"{nupkg.Id}.{nupkg.Version}.nupkg");
            var tempPath          = Path.GetTempFileName();

            using (var packageStream = await nupkg.CreateAsStreamAsync())
                using (var fileStream = File.OpenWrite(tempPath))
                {
                    packageStream.CopyTo(fileStream);
                }

            using (var originalPackage = File.OpenRead(tempPath))
                using (var signedPackage = File.Open(signedPackagePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    using (var request = new RepositorySignPackageRequest(
                               new X509Certificate2(certificate),
                               signatureHashAlgorithm,
                               timestampHashAlgorithm,
                               v3ServiceIndex,
                               packageOwners))
                    {
                        await CreateSignedPackageAsync(request, originalPackage, signedPackage, timestampService);
                    }

            FileUtility.Delete(tempPath);

            return(signedPackagePath);
        }
Beispiel #2
0
        public RepositorySignPackageRequest GetRepositorySignRequest()
        {
            ValidatePackagePath();
            WarnIfNoTimestamper(Console);
            ValidateCertificateInputs();
            EnsureOutputDirectory();
            ValidatePackageOwners();

            var signingSpec            = SigningSpecifications.V1;
            var signatureHashAlgorithm = ValidateAndParseHashAlgorithm(HashAlgorithm, nameof(HashAlgorithm), signingSpec);
            var timestampHashAlgorithm = ValidateAndParseHashAlgorithm(TimestampHashAlgorithm, nameof(TimestampHashAlgorithm), signingSpec);
            var v3ServiceIndexUri      = ValidateAndParseV3ServiceIndexUrl();

            var certCollection = GetCertificateCollection();
            var certificate    = GetCertificate(certCollection);
            var privateKey     = GetPrivateKey(certificate);

            var request = new RepositorySignPackageRequest(
                certificate,
                signatureHashAlgorithm,
                timestampHashAlgorithm,
                v3ServiceIndexUri,
                new ReadOnlyCollection <string>(PackageOwners))
            {
                PrivateKey = privateKey
            };

            request.AdditionalCertificates.AddRange(certCollection);

            return(request);
        }
            internal static async Task <Test> CreateAsync(
                X509Certificate2 certificate,
                Uri v3ServiceIndexUrl = null,
                IReadOnlyList <string> packageOwners = null)
            {
                v3ServiceIndexUrl = v3ServiceIndexUrl ?? new Uri("https://test.test");

                var packageContext = new SimpleTestPackageContext();
                var test           = await CreateWithoutRepositoryCountersignatureAsync(certificate);

                var request = new RepositorySignPackageRequest(
                    certificate,
                    HashAlgorithmName.SHA256,
                    HashAlgorithmName.SHA256,
                    SignaturePlacement.Countersignature,
                    v3ServiceIndexUrl,
                    packageOwners);
                var cmsSigner = SigningUtility.CreateCmsSigner(request, NullLogger.Instance);
                var signedCms = test.PrimarySignature.SignedCms;

                signedCms.SignerInfos[0].ComputeCounterSignature(cmsSigner);

                var primarySignature = PrimarySignature.Load(signedCms.Encode());

                return(new Test(request, primarySignature));
            }
        /// <summary>
        /// Generates an repository signed copy of a package and returns the path to that package
        /// This method can timestamp a package and should only be used with tests marked with [CIOnlyFact]
        /// </summary>
        /// <remarks>If the package is already author signed this method will repository countersign it</remarks>
        /// <param name="certificate">Certificate to be used while signing the package</param>
        /// <param name="packagePath">Package to be signed</param>
        /// <param name="outputDir">Directory for placing the signed package</param>
        /// <param name="timestampService">RFC 3161 timestamp service URL.</param>
        /// <param name="v3ServiceIndex">Value for the V3ServiceIndex for the repository signature attribute</param>
        /// <param name="packageOwners">List of package owners for teh repository signature attribute</param>
        /// <param name="signatureHashAlgorithm">Hash algorithm to be used in the signature. Defaults to SHA256</param>
        /// <param name="timestampHashAlgorithm">Hash algorithm to be used in the timestamp. Defaults to SHA256</param>
        /// <returns>Path to the signed copy of the package</returns>
        public static async Task <string> RepositorySignPackageAsync(
            X509Certificate2 certificate,
            string packagePath,
            string outputDir,
            Uri v3ServiceIndex,
            Uri timestampService = null,
            IReadOnlyList <string> packageOwners     = null,
            HashAlgorithmName signatureHashAlgorithm = HashAlgorithmName.SHA256,
            HashAlgorithmName timestampHashAlgorithm = HashAlgorithmName.SHA256)
        {
            var testLogger        = new TestLogger();
            var outputPackagePath = Path.Combine(outputDir, Guid.NewGuid().ToString());

            using (var originalPackage = File.OpenRead(packagePath))
                using (var signedPackage = File.Open(outputPackagePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    using (var request = new RepositorySignPackageRequest(
                               new X509Certificate2(certificate),
                               signatureHashAlgorithm,
                               timestampHashAlgorithm,
                               v3ServiceIndex,
                               packageOwners))
                    {
                        await CreateSignedPackageAsync(request, originalPackage, signedPackage, timestampService);
                    }

            return(outputPackagePath);
        }
        public async Task <bool> SignAsync(string packagePath, string outputPath, string timestampUrl, Uri v3ServiceIndex, IReadOnlyList <string> packageOwners,
                                           SignatureType signatureType, HashAlgorithmName signatureHashAlgorithm, HashAlgorithmName timestampHashAlgorithm,
                                           bool overwrite, X509Certificate2 publicCertificate, System.Security.Cryptography.RSA rsa, CancellationToken cancellationToken = default)
        {
            var packagesToSign = LocalFolderUtility.ResolvePackageFromPath(packagePath);

            var signatureProvider = new KeyVaultSignatureProvider(rsa, new Rfc3161TimestampProvider(new Uri(timestampUrl)));

            SignPackageRequest request = null;

            if (signatureType == SignatureType.Author)
            {
                request = new AuthorSignPackageRequest(publicCertificate, signatureHashAlgorithm, timestampHashAlgorithm);
            }
            else if (signatureType == SignatureType.Repository)
            {
                request = new RepositorySignPackageRequest(publicCertificate, signatureHashAlgorithm, timestampHashAlgorithm, v3ServiceIndex, packageOwners);
            }
            else
            {
                throw new ArgumentOutOfRangeException(nameof(signatureType));
            }

            string originalPackageCopyPath = null;

            foreach (var package in packagesToSign)
            {
                cancellationToken.ThrowIfCancellationRequested();
                logger.LogInformation($"{nameof(SignAsync)} [{package}]: Begin Signing {Path.GetFileName(package)}");
                try
                {
                    originalPackageCopyPath = CopyPackage(package);

                    using var options = SigningOptions.CreateFromFilePaths(originalPackageCopyPath, outputPath, overwrite, signatureProvider, new NuGetLogger(logger, package));
                    await SigningUtility.SignAsync(options, request, cancellationToken);
                }
                catch (Exception e)
                {
                    logger.LogError(e, e.Message);
                    return(false);
                }
                finally
                {
                    try
                    {
                        FileUtility.Delete(originalPackageCopyPath);
                    }
                    catch
                    {
                    }

                    logger.LogInformation($"{nameof(SignAsync)} [{package}]: End Signing {Path.GetFileName(package)}");
                }
            }

            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// Adds a Repository countersignature to a given primary signature
        /// </summary>
        /// <param name="testCert">Certificate to be used while generating the countersignature.</param>
        /// <param name="primarySignature">Primary signature to add countersignature.</param>
        /// <param name="timestampProvider">An optional timestamp provider.</param>
        /// <returns></returns>
        public static async Task <PrimarySignature> RepositoryCountersignPrimarySignatureAsync(
            X509Certificate2 testCert,
            PrimarySignature primarySignature,
            ITimestampProvider timestampProvider = null)
        {
            var testLogger        = new TestLogger();
            var hashAlgorithm     = HashAlgorithmName.SHA256;
            var v3ServiceIndexUrl = new Uri("https://v3serviceIndex.test/api/index.json");

            using (var request = new RepositorySignPackageRequest(testCert, hashAlgorithm, hashAlgorithm, v3ServiceIndexUrl, null))
            {
                var testSignatureProvider = new X509SignatureProvider(timestampProvider);

                return(await testSignatureProvider.CreateRepositoryCountersignatureAsync(request, primarySignature, testLogger, CancellationToken.None));
            }
        }
 public void Constructor_WithValidInput_InitializesProperties()
 {
     using (var certificate = new X509Certificate2())
         using (var request = new RepositorySignPackageRequest(
                    certificate,
                    HashAlgorithmName.SHA256,
                    HashAlgorithmName.SHA384,
                    _validV3ServiceIndexUrl,
                    _validPackageOwners))
         {
             Assert.Equal(SignatureType.Repository, request.SignatureType);
             Assert.Same(certificate, request.Certificate);
             Assert.Equal(HashAlgorithmName.SHA256, request.SignatureHashAlgorithm);
             Assert.Equal(HashAlgorithmName.SHA384, request.TimestampHashAlgorithm);
             Assert.Equal(_validV3ServiceIndexUrl.OriginalString, request.V3ServiceIndexUrl.OriginalString);
             Assert.Equal(_validPackageOwners, request.PackageOwners);
         }
 }
Beispiel #8
0
        /// <summary>
        /// Generates a SignedCMS object for some content.
        /// </summary>
        /// <param name="content"></param>
        /// <param name="cert">Certificate for cms signer</param>
        /// <returns>SignedCms object</returns>
        public static SignedCms GenerateRepositoryCountersignedSignedCms(X509Certificate2 cert, byte[] content)
        {
            var contentInfo   = new ContentInfo(content);
            var hashAlgorithm = NuGet.Common.HashAlgorithmName.SHA256;

            using (var primarySignatureRequest = new AuthorSignPackageRequest(new X509Certificate2(cert), hashAlgorithm))
                using (var countersignatureRequest = new RepositorySignPackageRequest(new X509Certificate2(cert), hashAlgorithm, hashAlgorithm, new Uri("https://api.nuget.org/v3/index.json"), null))
                {
                    var cmsSigner = SigningUtility.CreateCmsSigner(primarySignatureRequest, NullLogger.Instance);

                    var cms = new SignedCms(contentInfo);
                    cms.ComputeSignature(cmsSigner);

                    var counterCmsSigner = SigningUtility.CreateCmsSigner(countersignatureRequest, NullLogger.Instance);
                    cms.SignerInfos[0].ComputeCounterSignature(counterCmsSigner);

                    return(cms);
                }
        }
            private Test(X509Certificate2 certificate, TestDirectory dir, FileInfo package)
            {
                _authorCertificate     = new X509Certificate2(certificate);
                _repositoryCertificate = new X509Certificate2(certificate);
                _directory             = dir;

                var outputPath = GetNewTempFilePath();

                OutputFile = new FileInfo(outputPath);

                var signatureProvider = new X509SignatureProvider(timestampProvider: null);

                AuthorRequest     = new AuthorSignPackageRequest(_authorCertificate, HashAlgorithmName.SHA256);
                RepositoryRequest = new RepositorySignPackageRequest(_repositoryCertificate, HashAlgorithmName.SHA256, HashAlgorithmName.SHA256, new Uri("https://test/api/index.json"), packageOwners: null);

                var overwrite = true;

                Options = SigningOptions.CreateFromFilePaths(package.FullName, outputPath, overwrite, signatureProvider, NullLogger.Instance);
            }
        public async 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 getter = typeof(SignPackageRequest).GetProperty("Chain", BindingFlags.Instance | BindingFlags.NonPublic)
                         .GetGetMethod(true);

            var certs = (IReadOnlyList <X509Certificate2>)getter.Invoke(request, null);

            var cmsSigner = CreateCmsSigner(request, certs, logger);

            logger.LogInformation($"{nameof(CreateRepositoryCountersignatureAsync)}: Creating Counter signature");
            var signature = CreateKeyVaultRepositoryCountersignature(cmsSigner, request, primarySignature);

            logger.LogInformation($"{nameof(CreateRepositoryCountersignatureAsync)}: Counter signature completed");
            if (timestampProvider == null)
            {
                return(signature);
            }
            else
            {
                logger.LogInformation($"{nameof(CreateRepositoryCountersignatureAsync)}: Timestamp Counter signature");
                var timestamped = await TimestampRepositoryCountersignatureAsync(request, logger, signature, token).ConfigureAwait(false);

                logger.LogInformation($"{nameof(CreateRepositoryCountersignatureAsync)}: Timestamp completed");
                return(timestamped);
            }
        }
            internal async Task RepositorySignAsync()
            {
                using (var request = new RepositorySignPackageRequest(
                           new X509Certificate2(Certificate),
                           HashAlgorithmName.SHA256,
                           HashAlgorithmName.SHA256,
                           new Uri("https://test.test"),
                           packageOwners: null))
                    using (var originalPackage = new MemoryStream(Zip.ToByteArray(), writable: false))
                        using (var signedPackage = new MemoryStream())
                        {
                            await SignedArchiveTestUtility.CreateSignedPackageAsync(request, originalPackage, signedPackage);

                            SignedPackage = new MemoryStream(signedPackage.ToArray(), writable: false);
                        }

                var isSigned = await SignedArchiveTestUtility.IsSignedAsync(SignedPackage);

                Assert.True(isSigned);
            }
Beispiel #12
0
        public void CreateCmsSigner_WithRepositorySignPackageRequest_ReturnsInstance()
        {
            var v3ServiceIndexUrl = new Uri("https://test.test", UriKind.Absolute);
            var packageOwners     = new[] { "a", "b", "c" };

            using (var certificate = _fixture.GetDefaultCertificate())
                using (var request = new RepositorySignPackageRequest(
                           certificate,
                           Common.HashAlgorithmName.SHA256,
                           Common.HashAlgorithmName.SHA256,
                           v3ServiceIndexUrl,
                           packageOwners))
                {
                    var signer = SigningUtility.CreateCmsSigner(request, NullLogger.Instance);

                    Assert.Equal(request.Certificate, signer.Certificate);
                    Assert.Equal(request.SignatureHashAlgorithm.ConvertToOidString(), signer.DigestAlgorithm.Value);

                    VerifyAttributesRepository(signer.SignedAttributes, request);
                }
        }
Beispiel #13
0
            internal Test(X509Certificate2 certificate)
            {
                _directory             = TestDirectory.Create();
                _authorCertificate     = new X509Certificate2(certificate);
                _repositoryCertificate = new X509Certificate2(certificate);

                var outputPath = GetNewTempFilePath();

                OutputFile = new FileInfo(outputPath);

                var packageContext    = new SimpleTestPackageContext();
                var packageFileName   = Guid.NewGuid().ToString();
                var package           = packageContext.CreateAsFile(_directory, packageFileName);
                var signatureProvider = new X509SignatureProvider(timestampProvider: null);

                AuthorRequest     = new AuthorSignPackageRequest(_authorCertificate, HashAlgorithmName.SHA256);
                RepositoryRequest = new RepositorySignPackageRequest(_repositoryCertificate, HashAlgorithmName.SHA256, HashAlgorithmName.SHA256, new Uri("https://test/api/index.json"), packageOwners: null);

                var overwrite = true;

                Options = SigningOptions.CreateFromFilePaths(package.FullName, outputPath, overwrite, signatureProvider, NullLogger.Instance);
            }
            internal async Task RepositoryCountersignAsync()
            {
                PrimarySignature primarySignature;

                using (var archiveReader = new PackageArchiveReader(SignedPackage))
                {
                    primarySignature = await archiveReader.GetPrimarySignatureAsync(CancellationToken.None);
                }

                using (var request = new RepositorySignPackageRequest(
                           new X509Certificate2(Certificate),
                           HashAlgorithmName.SHA256,
                           HashAlgorithmName.SHA256,
                           new Uri("https://test.test"),
                           packageOwners: null))
                {
                    var cmsSigner = SigningUtility.CreateCmsSigner(request, NullLogger.Instance);
                    var signedCms = primarySignature.SignedCms;

                    signedCms.SignerInfos[0].ComputeCounterSignature(cmsSigner);

                    primarySignature = PrimarySignature.Load(signedCms.Encode());
                }

                using (var originalPackage = new MemoryStream(Zip.ToByteArray(), writable: false))
                    using (var signedPackage = new MemoryStream())
                        using (var archive = new SignedPackageArchive(originalPackage, signedPackage))
                            using (var signatureStream = new MemoryStream(primarySignature.GetBytes()))
                            {
                                await archive.AddSignatureAsync(signatureStream, CancellationToken.None);

                                SignedPackage = new MemoryStream(signedPackage.ToArray(), writable: false);
                            }

                var isSigned = await SignedArchiveTestUtility.IsSignedAsync(SignedPackage);

                Assert.True(isSigned);
            }
Beispiel #15
0
        private static void VerifyAttributesRepository(
            System.Security.Cryptography.CryptographicAttributeObjectCollection attributes,
            RepositorySignPackageRequest request)
        {
            VerifyAttributes(attributes, request);

            var nugetV3ServiceIndexUrlAttributeFound = false;
            var nugetPackageOwnersAttributeFound     = false;

            foreach (var attribute in attributes)
            {
                Assert.Equal(1, attribute.Values.Count);

                switch (attribute.Oid.Value)
                {
                case Oids.NuGetV3ServiceIndexUrl:
                    var nugetV3ServiceIndexUrl = NuGetV3ServiceIndexUrl.Read(attribute.Values[0].RawData);

                    Assert.True(nugetV3ServiceIndexUrl.V3ServiceIndexUrl.IsAbsoluteUri);
                    Assert.Equal(request.V3ServiceIndexUrl.OriginalString, nugetV3ServiceIndexUrl.V3ServiceIndexUrl.OriginalString);

                    nugetV3ServiceIndexUrlAttributeFound = true;
                    break;

                case Oids.NuGetPackageOwners:
                    var nugetPackageOwners = NuGetPackageOwners.Read(attribute.Values[0].RawData);

                    Assert.Equal(request.PackageOwners, nugetPackageOwners.PackageOwners);

                    nugetPackageOwnersAttributeFound = true;
                    break;
                }
            }

            Assert.True(nugetV3ServiceIndexUrlAttributeFound);
            Assert.Equal(request.PackageOwners != null && request.PackageOwners.Count > 0, nugetPackageOwnersAttributeFound);
        }
Beispiel #16
0
        public async Task HasRepositoryCountersignature_WithSignatureWithRepositoryCountersignature_ReturnsTrueAsync()
        {
            using (var certificate = _fixture.GetDefaultCertificate())
                using (var repositoryCertificate = _fixture.GetDefaultCertificate())
                {
                    var packageContext        = new SimpleTestPackageContext();
                    var unsignedPackageStream = packageContext.CreateAsStream();

                    var signature = await SignedArchiveTestUtility.CreateAuthorSignatureForPackageAsync(
                        certificate,
                        unsignedPackageStream);

                    var hashAlgorithm     = Common.HashAlgorithmName.SHA256;
                    var v3ServiceIndexUri = new Uri("https://v3serviceIndex.test/api/index.json");
                    using (var request = new RepositorySignPackageRequest(repositoryCertificate, hashAlgorithm, hashAlgorithm, v3ServiceIndexUri, null))
                    {
                        var reposignedSignature = await SignedArchiveTestUtility.RepositoryCountersignPrimarySignatureAsync(signature, request);

                        var hasRepoCountersignature = SignatureUtility.HasRepositoryCountersignature(reposignedSignature);

                        Assert.True(hasRepoCountersignature);
                    }
                }
        }
Beispiel #17
0
        private static async Task AddRepositoryCountersignatureToSignedPackageAsync(SimpleTestPackageContext packageContext, ISignedPackage package, RepositorySignPackageRequest request, ILogger logger)
        {
            var primarySignature = await package.GetPrimarySignatureAsync(CancellationToken.None);

            if (primarySignature != null)
            {
                var testSignatureProvider = new X509SignatureProvider(packageContext.CounterTimestampProvider);

                var signature = await testSignatureProvider.CreateRepositoryCountersignatureAsync(request, primarySignature, logger, CancellationToken.None);

                using (var stream = new MemoryStream(signature.GetBytes()))
                {
                    await package.AddSignatureAsync(stream, CancellationToken.None);
                }
            }
        }
Beispiel #18
0
        /// <summary>
        /// Write a zip file to a stream.
        /// </summary>
        public static async Task CreatePackageAsync(Stream stream, SimpleTestPackageContext packageContext)
        {
            var id                = packageContext.Id;
            var version           = packageContext.Version;
            var runtimeJson       = packageContext.RuntimeJson;
            var pathResolver      = new VersionFolderPathResolver(null);
            var testLogger        = new TestLogger();
            var tempStream        = stream;
            var isUsingTempStream = false;

            if (packageContext.IsPrimarySigned)
            {
                tempStream        = new MemoryStream();
                isUsingTempStream = true;
            }

            using (var zip = new ZipArchive(tempStream, ZipArchiveMode.Create, leaveOpen: true))
            {
                if (packageContext.Files.Any())
                {
                    foreach (var entryFile in packageContext.Files)
                    {
                        zip.AddEntry(entryFile.Key, entryFile.Value);
                    }
                }
                else
                {
                    zip.AddEntry("contentFiles/any/any/config.xml", new byte[] { 0 });
                    zip.AddEntry("contentFiles/cs/net45/code.cs", new byte[] { 0 });
                    zip.AddEntry("lib/net45/a.dll", new byte[] { 0 });
                    zip.AddEntry("lib/netstandard1.0/a.dll", new byte[] { 0 });
                    zip.AddEntry($"build/net45/{id}.targets", @"<targets />", Encoding.UTF8);
                    zip.AddEntry("runtimes/any/native/a.dll", new byte[] { 0 });
                    zip.AddEntry("tools/a.exe", new byte[] { 0 });
                }

                if (!string.IsNullOrEmpty(runtimeJson))
                {
                    zip.AddEntry("runtime.json", runtimeJson, Encoding.UTF8);
                }

                var frameworkAssembliesAndContentFiles = packageContext.UseDefaultRuntimeAssemblies ?
                                                         $@"<frameworkAssemblies>
                                <frameworkAssembly assemblyName=""System.Runtime""/>
                            </frameworkAssemblies>
                           <contentFiles>
                               <files include=""cs/net45/config/config.xml"" buildAction=""none"" />
                               <files include=""cs/net45/config/config.xml"" copyToOutput=""true"" flatten=""false"" />
                               <files include=""cs/net45/images/image.jpg"" buildAction=""embeddedresource"" />
                           </contentFiles>" :
                                                         string.Empty;

                var nuspecXml = packageContext.Nuspec?.ToString() ??
                                $@"<?xml version=""1.0"" encoding=""utf-8""?>
                        <package>
                        <metadata>
                            <id>{id}</id>
                            <version>{version.ToString()}</version>
                            <title />
                            {frameworkAssembliesAndContentFiles}
                        </metadata>
                        </package>";

                var xml = XDocument.Parse(nuspecXml);

                // Add the min client version if it exists
                if (!string.IsNullOrEmpty(packageContext.MinClientVersion))
                {
                    xml.Root.Element(XName.Get("metadata"))
                    .Add(new XAttribute(XName.Get("minClientVersion"), packageContext.MinClientVersion));
                }

                var dependencies = packageContext.Dependencies.Select(e =>
                                                                      new PackageDependency(
                                                                          e.Id,
                                                                          VersionRange.Parse(e.Version),
                                                                          string.IsNullOrEmpty(e.Include)
                            ? new List <string>()
                            : e.Include.Split(',').ToList(),
                                                                          string.IsNullOrEmpty(e.Exclude)
                            ? new List <string>()
                            : e.Exclude.Split(',').ToList()));

                if (dependencies.Any())
                {
                    var metadata = xml.Element(XName.Get("package")).Element(XName.Get("metadata"));

                    var dependenciesNode = new XElement(XName.Get("dependencies"));
                    var groupNode        = new XElement(XName.Get("group"));
                    dependenciesNode.Add(groupNode);
                    metadata.Add(dependenciesNode);

                    foreach (var dependency in dependencies)
                    {
                        var node = new XElement(XName.Get("dependency"));
                        groupNode.Add(node);
                        node.Add(new XAttribute(XName.Get("id"), dependency.Id));
                        node.Add(new XAttribute(XName.Get("version"), dependency.VersionRange.ToNormalizedString()));

                        if (dependency.Include.Count > 0)
                        {
                            node.Add(new XAttribute(XName.Get("include"), string.Join(",", dependency.Include)));
                        }

                        if (dependency.Exclude.Count > 0)
                        {
                            node.Add(new XAttribute(XName.Get("exclude"), string.Join(",", dependency.Exclude)));
                        }
                    }
                }

                if (packageContext.PackageTypes.Count > 0)
                {
                    var metadata     = xml.Element("package").Element("metadata");
                    var packageTypes = new XElement("packageTypes");
                    metadata.Add(packageTypes);

                    foreach (var packageType in packageContext.PackageTypes)
                    {
                        var packageTypeElement = new XElement("packageType");
                        packageTypeElement.Add(new XAttribute("name", packageType.Name));
                        if (packageType.Version != PackageType.EmptyVersion)
                        {
                            packageTypeElement.Add(new XAttribute("version", packageType.Version));
                        }

                        packageTypes.Add(packageTypeElement);
                    }
                }

                zip.AddEntry($"{id}.nuspec", xml.ToString(), Encoding.UTF8);
            }

            if (isUsingTempStream)
            {
#if IS_DESKTOP
                using (var signPackage = new SignedPackageArchive(tempStream, stream))
                {
                    using (var request = GetPrimarySignRequest(packageContext))
                    {
                        await AddSignatureToPackageAsync(packageContext, signPackage, request, testLogger);
                    }

                    if (packageContext.IsRepositoryCounterSigned)
                    {
                        using (var request = new RepositorySignPackageRequest(new X509Certificate2(packageContext.RepositoryCountersignatureCertificate),
                                                                              HashAlgorithmName.SHA256,
                                                                              HashAlgorithmName.SHA256,
                                                                              packageContext.V3ServiceIndexUrl,
                                                                              packageContext.PackageOwners))
                        {
                            await AddRepositoryCountersignatureToSignedPackageAsync(packageContext, signPackage, request, testLogger);
                        }
                    }
                }
#endif

                tempStream.Dispose();
            }

            // Reset position
            stream.Position = 0;
        }
        /// <summary>
        /// Adds a repository countersignature for a given primary signature for tests.
        /// </summary>
        /// <param name="signature">Primary signature to add the repository countersignature.</param>
        /// <param name="request">RepositorySignPackageRequest containing the metadata for the signature request.</param>
        /// <returns>Primary signature with a repository countersignature.</returns>
        public static async Task <PrimarySignature> RepositoryCountersignPrimarySignatureAsync(PrimarySignature signature, RepositorySignPackageRequest request)
        {
            var testLogger        = new TestLogger();
            var signatureProvider = new X509SignatureProvider(timestampProvider: null);

            return(await signatureProvider.CreateRepositoryCountersignatureAsync(request, signature, testLogger, CancellationToken.None));
        }
Beispiel #20
0
 /// <summary>
 /// Adds a repository countersignature for a given primary signature for tests.
 /// </summary>
 /// <param name="signatureProvider">Signature proivider to create the repository countersignature.</param>
 /// <param name="signature">Primary signature to add the repository countersignature.</param>
 /// <param name="request">RepositorySignPackageRequest containing the metadata for the signature request.</param>
 /// <param name="testLogger">ILogger.</param>
 /// <returns>Primary signature with a repository countersignature.</returns>
 public static async Task <PrimarySignature> RepositoryCountersignPrimarySignatureAsync(ISignatureProvider signatureProvider, PrimarySignature signature, RepositorySignPackageRequest request, TestLogger testLogger)
 {
     return(await signatureProvider.CreateRepositoryCountersignatureAsync(request, signature, testLogger, CancellationToken.None));
 }
Beispiel #21
0
 public Task <PrimarySignature> CreateRepositoryCountersignatureAsync(RepositorySignPackageRequest request, PrimarySignature primarySignature, ILogger logger, CancellationToken token)
 {
     throw new NotImplementedException();
 }
 private Test(RepositorySignPackageRequest request, PrimarySignature primarySignature)
 {
     Request          = request;
     PrimarySignature = primarySignature;
 }