Exemplo n.º 1
0
            internal static SignTest Create(
                X509Certificate2 certificate,
                HashAlgorithmName hashAlgorithm,
                byte[] package = null,
                ISignatureProvider signatureProvider = null)
            {
                ISignedPackage signedPackage;
                MemoryStream   readStream  = null;
                MemoryStream   writeStream = null;

                if (package == null)
                {
                    signedPackage = Mock.Of <ISignedPackage>();
                }
                else
                {
                    readStream    = new MemoryStream(package);
                    writeStream   = new MemoryStream();
                    signedPackage = new SignedPackageArchive(readStream, writeStream);
                }

                signatureProvider = signatureProvider ?? Mock.Of <ISignatureProvider>();
                var signer  = new Signer(signedPackage, signatureProvider);
                var request = new SignPackageRequest(certificate, signatureHashAlgorithm: hashAlgorithm);

                return(new SignTest(
                           signer,
                           signedPackage,
                           signatureProvider,
                           request,
                           readStream,
                           writeStream));
            }
        /// <summary>
        /// Generates a signed copy of a package and returns the path to that package
        /// This method timestamps 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="request">An author signing request.</param>
        /// <returns>Path to the signed copy of the package</returns>
        public static async Task <string> CreateSignedAndTimeStampedPackageAsync(
            X509Certificate2 certificate,
            SimpleTestPackageContext nupkg,
            string dir,
            Uri timestampService,
            AuthorSignPackageRequest request = null)
        {
            var testLogger = new TestLogger();

            using (var zipReadStream = nupkg.CreateAsStream())
                using (var zipWriteStream = nupkg.CreateAsStream())
                {
                    var signedPackagePath = Path.Combine(dir, Guid.NewGuid().ToString());

                    using (var signPackage = new SignedPackageArchive(zipReadStream, zipWriteStream))
                    {
                        request = request ?? new AuthorSignPackageRequest(certificate, HashAlgorithmName.SHA256);

                        // Sign the package
                        await SignAndTimeStampPackageAsync(testLogger, certificate, signPackage, timestampService, request);
                    }

                    zipWriteStream.Seek(offset: 0, loc: SeekOrigin.Begin);

                    using (Stream fileStream = File.OpenWrite(signedPackagePath))
                    {
                        zipWriteStream.CopyTo(fileStream);
                    }

                    return(signedPackagePath);
                }
        }
        /// <summary>
        /// Generates a signed copy of a package and returns the path to that package
        /// This method timestamps a package and should only be used with tests marked with [CIOnlyFact]
        /// </summary>
        /// <param name="testCert">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>
        /// <returns>Path to the signed copy of the package</returns>
        public static async Task <string> CreateSignedAndTimeStampedPackageAsync(
            X509Certificate2 testCert,
            SimpleTestPackageContext nupkg,
            string dir,
            Uri timestampService)
        {
            var testLogger = new TestLogger();

            using (var zipReadStream = nupkg.CreateAsStream())
                using (var zipWriteStream = nupkg.CreateAsStream())
                {
                    var signedPackagePath = Path.Combine(dir, Guid.NewGuid().ToString());

                    using (var signPackage = new SignedPackageArchive(zipReadStream, zipWriteStream))
                    {
                        // Sign the package
                        await SignAndTimeStampPackageAsync(testLogger, testCert, signPackage, timestampService);
                    }

                    zipWriteStream.Seek(offset: 0, loc: SeekOrigin.Begin);

                    using (Stream fileStream = File.OpenWrite(signedPackagePath))
                    {
                        zipWriteStream.CopyTo(fileStream);
                    }

                    return(signedPackagePath);
                }
        }
Exemplo n.º 4
0
            private Test(MemoryStream inputPackageStream)
            {
                InputPackageStream  = inputPackageStream;
                OutputPackageStream = new MemoryStream();

                Package = new SignedPackageArchive(InputPackageStream, OutputPackageStream);
            }
            internal async Task CountersignAsync()
            {
                PrimarySignature primarySignature;

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

                using (var request = new UnknownSignPackageRequest(
                           new X509Certificate2(Certificate),
                           HashAlgorithmName.SHA256))
                {
                    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);
            }
        public static async Task <VerifySignaturesResult> VerifySignatureAsync(SignedPackageArchive signPackage, SignedPackageVerifierSettings settings)
        {
            var verificationProviders = new[] { new SignatureTrustAndValidityVerificationProvider() };
            var verifier = new PackageSignatureVerifier(verificationProviders, settings);
            var result   = await verifier.VerifySignaturesAsync(signPackage, CancellationToken.None);

            return(result);
        }
Exemplo n.º 7
0
            internal Task <bool> IsSignedAsync()
            {
                using (var unused = new MemoryStream())
                {
                    var signedPackage = new SignedPackageArchive(_writeStream, unused);

                    return(signedPackage.IsSignedAsync(CancellationToken.None));
                }
            }
Exemplo n.º 8
0
 private VerifyTest(
     TestDirectory directory,
     SignedPackageArchive package,
     PrimarySignature primarySignature,
     SignatureVerifySettings settings)
 {
     _directory       = directory;
     Package          = package;
     PrimarySignature = primarySignature;
     Settings         = settings;
 }
Exemplo n.º 9
0
            internal Test(MemoryStream stream)
            {
                ReadStream  = stream;
                WriteStream = stream;

                Package = new SignedPackageArchive(ReadStream, WriteStream);

                var signatureProvider = new X509SignatureProvider(timestampProvider: null);

                Signer = new Signer(Package, signatureProvider);
            }
 private GetTrustResultAsyncTest(
     TestDirectory directory,
     SignedPackageArchive package,
     Signature signature,
     SignedPackageVerifierSettings settings)
 {
     _directory = directory;
     Package    = package;
     Signature  = signature;
     Settings   = settings;
     Provider   = new SignatureTrustAndValidityVerificationProvider();
 }
        /// <summary>
        /// Sign and timestamp a package for test purposes.
        /// This method timestamps a package and should only be used with tests marked with [CIOnlyFact]
        /// </summary>
        private static async Task SignAndTimeStampPackageAsync(
            TestLogger testLogger,
            X509Certificate2 certificate,
            SignedPackageArchive signPackage,
            Uri timestampService)
        {
            var testSignatureProvider = new X509SignatureProvider(new Rfc3161TimestampProvider(timestampService));
            var signer  = new Signer(signPackage, testSignatureProvider);
            var request = new AuthorSignPackageRequest(certificate, HashAlgorithmName.SHA256);

            await signer.SignAsync(request, testLogger, CancellationToken.None);
        }
 private VerifyTest(
     TestDirectory directory,
     FileStream signedPackageReadStream,
     SignedPackageArchive package,
     PrimarySignature primarySignature,
     SignatureVerifySettings settings)
 {
     _directory = directory;
     _signedPackageReadStream = signedPackageReadStream;
     Package          = package;
     PrimarySignature = primarySignature;
     Settings         = settings;
 }
Exemplo n.º 13
0
 private static async Task RemoveSignatureAsync(
     ILogger logger,
     ISignatureProvider signatureProvider,
     string packagePath,
     string originalPackageCopyPath,
     CancellationToken token)
 {
     using (var packageReadStream = File.OpenRead(packagePath))
         using (var packageWriteStream = File.Open(originalPackageCopyPath, FileMode.Open))
             using (var package = new SignedPackageArchive(packageReadStream, packageWriteStream))
             {
                 var signer = new Signer(package, signatureProvider);
                 await signer.RemoveSignaturesAsync(logger, token);
             }
 }
Exemplo n.º 14
0
 public static async Task CreateSignedPackageAsync(
     SignPackageRequest request,
     Stream packageReadStream,
     Stream packageWriteStream)
 {
     using (var signedPackage = new SignedPackageArchive(packageReadStream, packageWriteStream))
         using (var options = new SigningOptions(
                    new Lazy <Stream>(() => packageReadStream),
                    new Lazy <Stream>(() => packageWriteStream),
                    overwrite: false,
                    signatureProvider: new X509SignatureProvider(timestampProvider: null),
                    logger: NullLogger.Instance))
         {
             await SigningUtility.SignAsync(options, request, CancellationToken.None);
         }
 }
Exemplo n.º 15
0
            internal Test(X509Certificate2 certificate)
            {
                _directory   = TestDirectory.Create();
                _certificate = new X509Certificate2(certificate);

                var packageContext = new SimpleTestPackageContext();

                ReadStream  = packageContext.CreateAsStream();
                WriteStream = packageContext.CreateAsStream();

                Package = new SignedPackageArchive(ReadStream, WriteStream);
                Request = new AuthorSignPackageRequest(_certificate, HashAlgorithmName.SHA256);

                var signatureProvider = new X509SignatureProvider(timestampProvider: null);

                Signer = new Signer(Package, signatureProvider);
            }
            internal static async Task <GetTrustResultAsyncTest> CreateAsync(SignedPackageVerifierSettings settings, X509Certificate2 certificate)
            {
                using (var certificateClone = new X509Certificate2(certificate))
                {
                    var directory           = TestDirectory.Create();
                    var packageContext      = new SimpleTestPackageContext();
                    var unsignedPackageFile = packageContext.CreateAsFile(directory, "package.nupkg");
                    var signedPackageFile   = await SignedArchiveTestUtility.SignPackageFileWithBasicSignedCmsAsync(
                        directory,
                        unsignedPackageFile,
                        certificateClone);

                    var package   = new SignedPackageArchive(signedPackageFile.OpenRead(), new MemoryStream());
                    var signature = await package.GetSignatureAsync(CancellationToken.None);

                    return(new GetTrustResultAsyncTest(directory, package, signature, settings));
                }
            }
Exemplo n.º 17
0
        public async Task StripsRepositorySignatures()
        {
            // Arrange
            _message = new SignatureValidationMessage(
                TestResources.UnsignedPackageId,
                TestResources.UnsignedPackageVersion,
                new Uri($"https://unit.test/validation/{TestResources.UnsignedPackage.ToLowerInvariant()}"),
                Guid.NewGuid());
            var packageBytes = await _fixture.GenerateSignedPackageBytesAsync(
                TestResources.GetResourceStream(TestResources.UnsignedPackage),
                new RepositorySignPackageRequest(
                    await _fixture.GetSigningCertificateAsync(),
                    NuGetHashAlgorithmName.SHA256,
                    NuGetHashAlgorithmName.SHA256,
                    new Uri("https://example-source/v3/index.json"),
                    new[] { "nuget", "microsoft" }),
                await _fixture.GetTimestampServiceUrlAsync(),
                _output);

            var packageStream = new MemoryStream(packageBytes);

            TestUtility.RequireUnsignedPackage(_corePackageService, TestResources.UnsignedPackageId);

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Succeeded, PackageSigningStatus.Unsigned);
            Assert.Empty(result.Issues);
            Assert.Equal(_nupkgUri, result.NupkgUri);
            Assert.NotNull(_savedPackageBytes);
            using (var savedPackageStream = new MemoryStream(_savedPackageBytes))
                using (var packageReader = new SignedPackageArchive(savedPackageStream, Stream.Null))
                {
                    Assert.Equal("TestUnsigned", packageReader.NuspecReader.GetId());
                    Assert.Equal("1.0.0", packageReader.NuspecReader.GetVersion().ToNormalizedString());
                    Assert.False(await packageReader.IsSignedAsync(CancellationToken.None), "The package should no longer be signed.");
                }
        }
        // This generates a package with a basic signed CMS.
        // The signature MUST NOT have any signed or unsigned attributes.
        public static async Task <FileInfo> SignPackageFileWithBasicSignedCmsAsync(
            TestDirectory directory,
            FileInfo packageFile,
            X509Certificate2 certificate)
        {
            var signatureContent  = CreateSignatureContent(packageFile);
            var signedPackageFile = new FileInfo(Path.Combine(directory, Guid.NewGuid().ToString()));
            var signature         = CreateSignature(signatureContent, certificate);

            using (var packageReadStream = packageFile.OpenRead())
                using (var packageWriteStream = signedPackageFile.OpenWrite())
                    using (var package = new SignedPackageArchive(packageReadStream, packageWriteStream))
                        using (var signatureStream = new MemoryStream(signature.Encode()))
                        {
                            await package.AddSignatureAsync(signatureStream, CancellationToken.None);
                        }

            return(signedPackageFile);
        }
Exemplo n.º 19
0
        public async Task <SignatureValidatorResult> ValidateAsync(
            int packageKey,
            Stream packageStream,
            SignatureValidationMessage message,
            CancellationToken cancellationToken)
        {
            using (var packageReader = new SignedPackageArchive(packageStream, packageWriteStream: Stream.Null))
                using (var context = new Context(packageKey, packageStream, packageReader, message, cancellationToken))
                {
                    // Reject Zip64 package whether or not they are signed.
                    if (await context.PackageReader.IsZip64Async(context.CancellationToken))
                    {
                        return(await RejectAsync(context, ValidationIssue.PackageIsZip64));
                    }

                    SignatureValidatorResult result;

                    if (await context.PackageReader.IsSignedAsync(cancellationToken))
                    {
                        result = await HandleSignedPackageAsync(context);
                    }
                    else
                    {
                        result = await HandleUnsignedPackageAsync(context);
                    }

                    // Force the validation to fail if the repository signature is expected but missing. The signature
                    // and signing state that are stored in the database may be still valid.
                    if (context.Message.RequireRepositorySignature && !context.HasRepositorySignature)
                    {
                        _logger.LogCritical(
                            "Package {PackageId} {PackageVersion} for validation {ValidationId} is expected to be repository signed.",
                            context.Message.PackageId,
                            context.Message.PackageVersion,
                            context.Message.ValidationId);

                        return(new SignatureValidatorResult(ValidationStatus.Failed, result.Issues, nupkgUri: null));
                    }

                    return(result);
                }
        }
Exemplo n.º 20
0
        private static async Task AddSignatureAndUpdatePackageAsync(
            ILogger logger,
            ISignatureProvider signatureProvider,
            AuthorSignPackageRequest request,
            string packagePath,
            string outputPath,
            CancellationToken token)
        {
            var originalPackageCopyPath = CopyPackage(packagePath);

            using (var packageReadStream = File.OpenRead(packagePath))
                using (var packageWriteStream = File.Open(originalPackageCopyPath, FileMode.Open))
                    using (var package = new SignedPackageArchive(packageReadStream, packageWriteStream))
                    {
                        var signer = new Signer(package, signatureProvider);
                        await signer.SignAsync(request, logger, token);
                    }

            OverwritePackage(originalPackageCopyPath, outputPath);
            FileUtility.Delete(originalPackageCopyPath);
        }
        private static async Task TestRemoveSignatureAsync(byte[] expectedPackage, byte[] signedPackage)
        {
            using (var readStream = new MemoryStream(signedPackage))
                using (var writeStream = new MemoryStream())
                    using (var signedArchive = new SignedPackageArchive(readStream, writeStream))
                    {
                        var isSigned = await SignedArchiveTestUtility.IsSignedAsync(readStream);

                        Assert.True(isSigned);

                        await signedArchive.RemoveSignatureAsync(CancellationToken.None);

                        isSigned = await SignedArchiveTestUtility.IsSignedAsync(writeStream);

                        Assert.False(isSigned);

                        var unsignedPackage = writeStream.ToArray();

                        Assert.Equal(expectedPackage, unsignedPackage);
                    }
        }
Exemplo n.º 22
0
        public async Task StripsRepositoryCounterSignatures()
        {
            // Arrange
            var packageBytes = await _fixture.GenerateSignedPackageBytesAsync(
                await GetSignedPackageStream1Async(),
                new RepositorySignPackageRequest(
                    await _fixture.GetSigningCertificateAsync(),
                    NuGetHashAlgorithmName.SHA256,
                    NuGetHashAlgorithmName.SHA256,
                    new Uri("https://example-source/v3/index.json"),
                    new[] { "nuget", "microsoft" }),
                await _fixture.GetTimestampServiceUrlAsync(),
                _output);

            var packageStream = new MemoryStream(packageBytes);

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Succeeded, PackageSigningStatus.Valid);
            Assert.Empty(result.Issues);
            Assert.Equal(_nupkgUri, result.NupkgUri);
            Assert.NotNull(_savedPackageBytes);
            using (var savedPackageStream = new MemoryStream(_savedPackageBytes))
                using (var packageReader = new SignedPackageArchive(savedPackageStream, Stream.Null))
                {
                    Assert.Equal("TestSigned.leaf-1", packageReader.NuspecReader.GetId());
                    Assert.Equal("1.0.0", packageReader.NuspecReader.GetVersion().ToNormalizedString());
                    Assert.True(await packageReader.IsSignedAsync(CancellationToken.None), "The package should still be signed.");
                    var signature = await packageReader.GetPrimarySignatureAsync(CancellationToken.None);

                    Assert.Equal(SignatureType.Author, signature.Type);
                    Assert.Empty(signature.SignedCms.SignerInfos[0].CounterSignerInfos);
                }
        }
Exemplo n.º 23
0
        // This generates a package with a basic signed CMS.
        // The signature MUST NOT have any signed or unsigned attributes.
        public static async Task <FileInfo> SignPackageFileWithBasicSignedCmsAsync(
            TestDirectory directory,
            FileInfo packageFile,
            X509Certificate2 certificate)
        {
            SignatureContent signatureContent;

            using (var stream = packageFile.OpenRead())
                using (var hashAlgorithm = HashAlgorithmName.SHA256.GetHashProvider())
                {
                    var hash = hashAlgorithm.ComputeHash(stream, leaveStreamOpen: false);
                    signatureContent = new SignatureContent(SigningSpecifications.V1, HashAlgorithmName.SHA256, Convert.ToBase64String(hash));
                }

            var signedPackageFile = new FileInfo(Path.Combine(directory, Guid.NewGuid().ToString()));
            var cmsSigner         = new CmsSigner(certificate)
            {
                DigestAlgorithm = HashAlgorithmName.SHA256.ConvertToOid(),
                IncludeOption   = X509IncludeOption.WholeChain
            };

            var contentInfo = new ContentInfo(signatureContent.GetBytes());
            var signature   = new SignedCms(contentInfo);

            signature.ComputeSignature(cmsSigner);

            Assert.Empty(signature.SignerInfos[0].SignedAttributes);
            Assert.Empty(signature.SignerInfos[0].UnsignedAttributes);

            using (var packageReadStream = packageFile.OpenRead())
                using (var packageWriteStream = signedPackageFile.OpenWrite())
                    using (var package = new SignedPackageArchive(packageReadStream, packageWriteStream))
                        using (var signatureStream = new MemoryStream(signature.Encode()))
                        {
                            await package.AddSignatureAsync(signatureStream, CancellationToken.None);
                        }

            return(signedPackageFile);
        }
Exemplo n.º 24
0
        public async Task <SignatureValidatorResult> ValidateAsync(
            int packageKey,
            Stream packageStream,
            SignatureValidationMessage message,
            CancellationToken cancellationToken)
        {
            using (var packageReader = new SignedPackageArchive(packageStream, packageWriteStream: Stream.Null))
                using (var context = new Context(packageKey, packageStream, packageReader, message, cancellationToken))
                {
                    // Reject Zip64 package whether or not they are signed.
                    if (await context.PackageReader.IsZip64Async(context.CancellationToken))
                    {
                        return(await RejectAsync(context, ValidationIssue.PackageIsZip64));
                    }

                    if (await context.PackageReader.IsSignedAsync(cancellationToken))
                    {
                        return(await HandleSignedPackageAsync(context));
                    }

                    return(await HandleUnsignedPackageAsync(context));
                }
        }
        /// <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", @"<Project />", 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));
                }

                List <(string, List <PackageDependency>)> dependenciesPerFramework = GetPackageDependencies(packageContext);

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

                    foreach (var deps in dependenciesPerFramework)
                    {
                        var groupNode = new XElement(XName.Get("group"));
                        if (!string.IsNullOrEmpty(deps.Item1))
                        {
                            groupNode.SetAttributeValue("targetFramework", deps.Item1);
                        }
                        dependenciesNode.Add(groupNode);
                        metadata.Add(dependenciesNode);

                        foreach (var dependency in deps.Item2)
                        {
                            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.FrameworkReferences.Any())
                {
                    var metadata = xml.Element(XName.Get("package")).Element(XName.Get("metadata"));
                    var frameworkReferencesNode = new XElement(XName.Get("frameworkReferences"));

                    foreach (var kvp in packageContext.FrameworkReferences)
                    {
                        var groupNode = new XElement(XName.Get("group"));
                        groupNode.SetAttributeValue("targetFramework", kvp.Key.GetFrameworkString());
                        frameworkReferencesNode.Add(groupNode);
                        metadata.Add(frameworkReferencesNode);

                        foreach (var frameworkReference in kvp.Value)
                        {
                            var node = new XElement(XName.Get("frameworkReference"));
                            groupNode.Add(node);
                            node.Add(new XAttribute(XName.Get("name"), frameworkReference));
                        }
                    }
                }

                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)
            {
                using (tempStream)
#if IS_SIGNING_SUPPORTED
                    using (var signPackage = new SignedPackageArchive(tempStream, stream))
#endif
                {
#if IS_SIGNING_SUPPORTED
                    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
                }
            }

            // Reset position
            stream.Position = 0;
        }
Exemplo n.º 26
0
        /// <summary>
        /// Sign a package for test purposes.
        /// </summary>
        public static async Task SignPackageAsync(TestLogger testLogger, X509Certificate2 certificate, SignedPackageArchive signPackage)
        {
            var testSignatureProvider = new X509SignatureProvider(new Rfc3161TimestampProvider(new Uri(_testTimestampServer)));
            var signer  = new Signer(signPackage, testSignatureProvider);
            var request = new SignPackageRequest(certificate, signatureHashAlgorithm: Common.HashAlgorithmName.SHA256);

            await signer.SignAsync(request, testLogger, CancellationToken.None);
        }
        /// <summary>
        /// Sign a package for test purposes.
        /// This does not timestamp a signature and can be used outside corp network.
        /// </summary>
        private static async Task SignPackageAsync(TestLogger testLogger, X509Certificate2 certificate, SignedPackageArchive signPackage)
        {
            var testSignatureProvider = new X509SignatureProvider(timestampProvider: null);
            var signer  = new Signer(signPackage, testSignatureProvider);
            var request = new SignPackageRequest(certificate, signatureHashAlgorithm: HashAlgorithmName.SHA256);

            await signer.SignAsync(request, testLogger, CancellationToken.None);
        }
Exemplo n.º 28
0
        public async Task <int> SignAsync(string file,
                                          string timestampUrl,
                                          HashAlgorithmName signatureHashAlgorithm,
                                          HashAlgorithmName timestampeHashAlgorithm,
                                          string keyVaultCertificateName,
                                          string keyVaultUrl,
                                          string keyVaultClientId,
                                          string keyVaultClientSecret,
                                          string keyVaultAccessToken)
        {
            string validatedToken = null;

            async Task <string> Authenticate(string authority, string resource, string scope)
            {
                if (!string.IsNullOrWhiteSpace(keyVaultAccessToken))
                {
                    validatedToken = keyVaultAccessToken;
                    return(keyVaultAccessToken);
                }

                var context    = new AuthenticationContext(authority);
                var credential = new ClientCredential(keyVaultClientId, keyVaultClientSecret);

                var result = await context.AcquireTokenAsync(resource, credential)
                             .ConfigureAwait(false);

                if (result == null)
                {
                    throw new InvalidOperationException("Authentication to Azure failed.");
                }
                validatedToken = result.AccessToken;
                return(result.AccessToken);
            }

            var client = new KeyVaultClient(Authenticate, new HttpClient());

            // We call this here to verify it's a valid cert
            // It also implicitly validates the access token or credentials
            var kvcert = await client.GetCertificateAsync(keyVaultUrl, keyVaultCertificateName)
                         .ConfigureAwait(false);

            var cert = new X509Certificate2(kvcert.Cer);



            var rsa = client.ToRSA(kvcert.KeyIdentifier, cert);

            // TODO: Add Hash Alg choice
            var request = new SignPackageRequest()
            {
                Certificate            = cert,
                SignatureHashAlgorithm = signatureHashAlgorithm,
                TimestampHashAlgorithm = timestampeHashAlgorithm
            };

            string tempFilePath = null;

            try
            {
                tempFilePath = CopyPackage(file);
                var signatureProvider = new KeyVaultSignatureProvider(rsa, new Rfc3161TimestampProvider(new Uri(timestampUrl)));

                // remove first to overwrite
                // This command overwrites by default, like signtool
                using (var packageWriteStream = File.Open(tempFilePath, FileMode.Open))
                    using (var package = new SignedPackageArchive(packageWriteStream))
                    {
                        var signer = new Signer(package, signatureProvider);
                        await signer.RemoveSignaturesAsync(new NullLogger(), CancellationToken.None);
                    }

                // Now sign
                using (var packageWriteStream = File.Open(tempFilePath, FileMode.Open))
                    using (var package = new SignedPackageArchive(packageWriteStream))
                    {
                        var signer = new Signer(package, signatureProvider);
                        await signer.SignAsync(request, new NullLogger(), CancellationToken.None);
                    }

                OverwritePackage(tempFilePath, file);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
                Console.Error.WriteLine(e.StackTrace);
                return(-1);
            }
            finally
            {
                try
                {
                    FileUtility.Delete(tempFilePath);
                }
                catch
                {
                }
            }

            return(0);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Write a zip file to a stream.
        /// </summary>
        public static void CreatePackage(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.AuthorSignatureCertificate != null)
            {
                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)
            {
                using (var signPackage = new SignedPackageArchive(tempStream, stream))
                {
                    var testSignatureProvider = new X509SignatureProvider(timestampProvider: null);
                    var signer  = new Signer(signPackage, testSignatureProvider);
                    var request = new AuthorSignPackageRequest(packageContext.AuthorSignatureCertificate, hashAlgorithm: HashAlgorithmName.SHA256);

                    signer.SignAsync(request, testLogger, CancellationToken.None).Wait();
                }

                tempStream.Dispose();
            }

            // Reset position
            stream.Position = 0;
        }