PrimarySignature CreateKeyVaultPrimarySignature(SignPackageRequest request, SignatureContent signatureContent, ILogger logger)
        {
            // Get the chain

            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);

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

            try
            {
                cms.ComputeSignature(cmsSigner, false); // silent is false to ensure PIN prompts appear if CNG/CAPI requires it
            }
            catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT)
            {
                var exceptionBuilder = new StringBuilder();

                exceptionBuilder.AppendLine("Invalid provider type");
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, NuGet.Common.HashAlgorithmName.SHA256));

                throw new SignatureException(NuGetLogCode.NU3001, exceptionBuilder.ToString());
            }

            return(PrimarySignature.Load(cms));
        }
Esempio n. 2
0
        public async Task <byte[]> GenerateSignedPackageBytesAsync(
            Stream inputPackageStream,
            SignPackageRequest request,
            Uri timestampUri,
            ITestOutputHelper output)
        {
            var testLogger        = new TestLogger(output);
            var timestampProvider = new Rfc3161TimestampProvider(timestampUri);
            var signatureProvider = new X509SignatureProvider(timestampProvider);

            using (var outputPackageStream = new MemoryStream())
            {
                await SigningUtility.SignAsync(
                    new SigningOptions(
                        inputPackageStream : new Lazy <Stream>(() => inputPackageStream),
                        outputPackageStream : new Lazy <Stream>(() => outputPackageStream),
                        overwrite : true,
                        signatureProvider : signatureProvider,
                        logger : testLogger),
                    request,
                    CancellationToken.None);

                return(outputPackageStream.ToArray());
            }
        }
        public async Task <PrimarySignature> CreatePrimarySignatureAsync(SignPackageRequest request, SignatureContent signatureContent, ILogger logger, CancellationToken token)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (signatureContent == null)
            {
                throw new ArgumentNullException(nameof(signatureContent));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Creating Primary signature");
            var authorSignature = CreateKeyVaultPrimarySignature(request, signatureContent, logger);

            logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Primary signature completed");

            logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Timestamp primary signature");
            var timestamped = await TimestampPrimarySignatureAsync(request, logger, authorSignature, token);

            logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Timestamp completed");

            return(timestamped);
        }
        private async Task <int> SignPackageAsync(
            string packagePath,
            string outputPath,
            ILogger logger,
            bool Overwrite,
            ISignatureProvider signatureProvider,
            SignPackageRequest request,
            CancellationToken token)
        {
            // For overwrite we need to first remove the signature and then sign the unsigned package
            if (Overwrite)
            {
                var originalPackageCopyPath = CopyPackage(packagePath);

                await RemoveSignatureAsync(logger, signatureProvider, packagePath, originalPackageCopyPath, token);
                await AddSignatureAndUpdatePackageAsync(logger, signatureProvider, request, originalPackageCopyPath, outputPath, token);

                FileUtility.Delete(originalPackageCopyPath);
            }
            else
            {
                await AddSignatureAndUpdatePackageAsync(logger, signatureProvider, request, packagePath, outputPath, token);
            }

            return(0);
        }
Esempio n. 5
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>
        /// 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)
        {
            var testSignatureProvider = new X509SignatureProvider(new Rfc3161TimestampProvider(new Uri(_testTimestampServer)));
            var signer  = new Signer(signPackage, testSignatureProvider);
            var request = new SignPackageRequest(certificate, signatureHashAlgorithm: HashAlgorithmName.SHA256);

            await signer.SignAsync(request, testLogger, CancellationToken.None);
        }
        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);
        }
        public async Task <int> ExecuteCommandAsync(
            IEnumerable <string> packagesToSign,
            SignPackageRequest signPackageRequest,
            string timestamper,
            ILogger logger,
            string outputDirectory,
            bool overwrite,
            CancellationToken token)
        {
            var success = true;

            try
            {
                SigningUtility.Verify(signPackageRequest);
            }
            catch (Exception e)
            {
                success = false;
                ExceptionUtilities.LogException(e, logger);
            }

            if (success)
            {
                var signatureProvider = GetSignatureProvider(timestamper);

                foreach (var packagePath in packagesToSign)
                {
                    try
                    {
                        string outputPath;

                        if (string.IsNullOrEmpty(outputDirectory))
                        {
                            outputPath = packagePath;
                        }
                        else
                        {
                            outputPath = Path.Combine(outputDirectory, Path.GetFileName(packagePath));
                        }

                        await SignPackageAsync(packagePath, outputPath, logger, overwrite, signatureProvider, signPackageRequest, token);
                    }
                    catch (Exception e)
                    {
                        success = false;
                        ExceptionUtilities.LogException(e, logger);
                    }
                }
            }

            if (success)
            {
                logger.LogInformation(Strings.SignCommandSuccess);
            }

            return(success ? 0 : 1);
        }
Esempio n. 9
0
        PrimarySignature CreateKeyVaultPrimarySignature(SignPackageRequest request, SignatureContent signatureContent, SignatureType signatureType)
        {
            // Get the chain

            var getter = typeof(SignPackageRequest).GetProperty("Chain", BindingFlags.Instance | BindingFlags.NonPublic)
                         .GetGetMethod(true);

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


            var attribs = SigningUtility.CreateSignedAttributes(request, certs);

            // Convert .NET crypto attributes to Bouncy Castle
            var attribTable = new AttributeTable(new Asn1EncodableVector(attribs.Cast <CryptographicAttributeObject>()
                                                                         .Select(ToBcAttribute)
                                                                         .ToArray()));
            // SignerInfo generator setup
            var signerInfoGeneratorBuilder = new SignerInfoGeneratorBuilder()
                                             .WithSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(attribTable));


            // Subject Key Identifier (SKI) is smaller and less prone to accidental matching than issuer and serial
            // number.  However, to ensure cross-platform verification, SKI should only be used if the certificate
            // has the SKI extension attribute.

            // Try to look for the value
            var bcCer = DotNetUtilities.FromX509Certificate(request.Certificate);
            var ext   = bcCer.GetExtensionValue(new DerObjectIdentifier(Oids.SubjectKeyIdentifier));
            SignerInfoGenerator signerInfoGenerator;

            if (ext != null)
            {
                var ski = new SubjectKeyIdentifierStructure(ext);
                signerInfoGenerator = signerInfoGeneratorBuilder.Build(new RsaSignatureFactory(HashAlgorithmToBouncyCastle(request.SignatureHashAlgorithm), provider), ski.GetKeyIdentifier());
            }
            else
            {
                signerInfoGenerator = signerInfoGeneratorBuilder.Build(new RsaSignatureFactory(HashAlgorithmToBouncyCastle(request.SignatureHashAlgorithm), provider), bcCer);
            }


            var generator = new CmsSignedDataGenerator();

            generator.AddSignerInfoGenerator(signerInfoGenerator);

            // Get the chain as bc certs
            generator.AddCertificates(X509StoreFactory.Create("Certificate/Collection",
                                                              new X509CollectionStoreParameters(certs.Select(DotNetUtilities.FromX509Certificate).
                                                                                                ToList())));

            var msg  = new CmsProcessableByteArray(signatureContent.GetBytes());
            var data = generator.Generate(msg, true);

            var encoded = data.ContentInfo.GetDerEncoded();

            return(PrimarySignature.Load(encoded));
        }
Esempio n. 10
0
 private SignTest(SignPackageRequest request,
                  TestDirectory directory,
                  SigningOptions options,
                  TestLogger logger)
 {
     Request    = request;
     Options    = options;
     Logger     = logger;
     _directory = directory;
 }
        CmsSigner CreateCmsSigner(SignPackageRequest request, IReadOnlyList <X509Certificate2> chain, ILogger logger)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            // Subject Key Identifier (SKI) is smaller and less prone to accidental matching than issuer and serial
            // number.  However, to ensure cross-platform verification, SKI should only be used if the certificate
            // has the SKI extension attribute.
            CmsSigner signer;

            if (request.Certificate.Extensions[Oids.SubjectKeyIdentifier] == null)
            {
                signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, request.Certificate, provider);
            }
            else
            {
                signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, request.Certificate, provider);
            }

            foreach (var certificate in chain)
            {
                signer.Certificates.Add(certificate);
            }

            CryptographicAttributeObjectCollection attributes;

            if (request.SignatureType == SignatureType.Repository)
            {
                attributes = SigningUtility.CreateSignedAttributes((RepositorySignPackageRequest)request, chain);
            }
            else
            {
                attributes = SigningUtility.CreateSignedAttributes(request, chain);
            }

            foreach (var attribute in attributes)
            {
                signer.SignedAttributes.Add(attribute);
            }

            // We built the chain ourselves and added certificates.
            // Passing any other value here would trigger another chain build
            // and possibly add duplicate certs to the collection.
            signer.IncludeOption   = X509IncludeOption.None;
            signer.DigestAlgorithm = request.SignatureHashAlgorithm.ConvertToOid();

            return(signer);
        }
Esempio n. 12
0
        Task <Signature> TimestampSignature(SignPackageRequest request, ILogger logger, byte[] signature, CancellationToken token)
        {
            var timestampRequest = new TimestampRequest
            {
                SignatureValue         = signature,
                Certificate            = request.Certificate,
                SigningSpec            = SigningSpecifications.V1,
                TimestampHashAlgorithm = request.TimestampHashAlgorithm
            };

            return(timestampProvider.TimestampSignatureAsync(timestampRequest, logger, token));
        }
Esempio n. 13
0
        private static void VerifyAttributes(
            CryptographicAttributeObjectCollection attributes,
            SignPackageRequest request)
        {
            var pkcs9SigningTimeAttributeFound         = false;
            var commitmentTypeIndicationAttributeFound = false;
            var signingCertificateV2AttributeFound     = false;

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

                switch (attribute.Oid.Value)
                {
                case "1.2.840.113549.1.9.5":     // PKCS #9 signing time
                    Assert.IsType <Pkcs9SigningTime>(attribute.Values[0]);

                    pkcs9SigningTimeAttributeFound = true;
                    break;

                case Oids.CommitmentTypeIndication:
                    var qualifier = CommitmentTypeQualifier.Read(attribute.Values[0].RawData);
                    var expectedCommitmentType = AttributeUtility.GetSignatureTypeOid(request.SignatureType);

                    Assert.Equal(expectedCommitmentType, qualifier.CommitmentTypeIdentifier.Value);

                    commitmentTypeIndicationAttributeFound = true;
                    break;

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

                    Assert.Equal(1, signingCertificateV2.Certificates.Count);

                    var essCertIdV2 = signingCertificateV2.Certificates[0];

                    Assert.Equal(SignTestUtility.GetHash(request.Certificate, request.SignatureHashAlgorithm), essCertIdV2.CertificateHash);
                    Assert.Equal(request.SignatureHashAlgorithm.ConvertToOidString(), essCertIdV2.HashAlgorithm.Algorithm.Value);
                    Assert.Equal(request.Certificate.IssuerName.Name, essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name);
                    SignTestUtility.VerifySerialNumber(request.Certificate, essCertIdV2.IssuerSerial);
                    Assert.Null(signingCertificateV2.Policies);

                    signingCertificateV2AttributeFound = true;
                    break;
                }
            }

            Assert.True(pkcs9SigningTimeAttributeFound);
            Assert.True(commitmentTypeIndicationAttributeFound);
            Assert.True(signingCertificateV2AttributeFound);
        }
        Task <PrimarySignature> TimestampPrimarySignatureAsync(SignPackageRequest request, ILogger logger, PrimarySignature signature, CancellationToken token)
        {
            var signatureValue = signature.GetSignatureValue();
            var messageHash    = request.TimestampHashAlgorithm.ComputeHash(signatureValue);

            var timestampRequest = new TimestampRequest(
                signingSpecifications: SigningSpecifications.V1,
                hashedMessage: messageHash,
                hashAlgorithm: request.TimestampHashAlgorithm,
                target: SignaturePlacement.PrimarySignature
                );

            return(timestampProvider.TimestampSignatureAsync(signature, timestampRequest, logger, token));
        }
Esempio n. 15
0
 private SignTest(Signer signer,
                  ISignedPackage package,
                  ISignatureProvider signatureProvider,
                  SignPackageRequest request,
                  MemoryStream readStream,
                  MemoryStream writeStream)
 {
     Signer            = signer;
     Package           = package;
     SignatureProvider = signatureProvider;
     Request           = request;
     _readStream       = readStream;
     _writeStream      = writeStream;
 }
Esempio n. 16
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);
         }
 }
        /// <summary>
        /// Generates a Signature for a given package for tests.
        /// </summary>
        /// <param name="package">Package to be used for the signature.</param>
        /// <param name="request">Sign package request for primary signature</param>
        /// <param name="timestampProvider">Provider to add timestamp to package. Defaults to null.</param>
        /// <returns>Signature for the package.</returns>
        public static async Task <PrimarySignature> CreatePrimarySignatureForPackageAsync(
            PackageArchiveReader package,
            SignPackageRequest request,
            ITimestampProvider timestampProvider = null)
        {
            Assert.False(await package.IsSignedAsync(CancellationToken.None));

            var testLogger        = new TestLogger();
            var signatureProvider = new X509SignatureProvider(timestampProvider);

            var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None);

            var base64ZipArchiveHash = Convert.ToBase64String(zipArchiveHash);
            var signatureContent     = new SignatureContent(SigningSpecifications.V1, request.SignatureHashAlgorithm, base64ZipArchiveHash);

            return(await signatureProvider.CreatePrimarySignatureAsync(request, signatureContent, testLogger, CancellationToken.None));
        }
        /// <summary>
        /// Generates a Signature for a package.
        /// </summary>
        /// <param name="testCert">Certificate to be used while generating the signature.</param>
        /// <param name="nupkg">Package for which the signature has to be generated.</param>
        /// <returns>Signature for the package.</returns>
        public static async Task <Signature> CreateSignatureForPackageAsync(X509Certificate2 testCert, Stream packageStream)
        {
            var testLogger    = new TestLogger();
            var hashAlgorithm = HashAlgorithmName.SHA256;

            using (var request = new SignPackageRequest(testCert, hashAlgorithm))
                using (var package = new PackageArchiveReader(packageStream, leaveStreamOpen: true))
                {
                    var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None);

                    var base64ZipArchiveHash  = Convert.ToBase64String(zipArchiveHash);
                    var signatureContent      = new SignatureContent(SigningSpecifications.V1, hashAlgorithm, base64ZipArchiveHash);
                    var testSignatureProvider = new X509SignatureProvider(timestampProvider: null);

                    return(await testSignatureProvider.CreateSignatureAsync(request, signatureContent, testLogger, CancellationToken.None));
                }
        }
Esempio n. 19
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 SignPackageRequest(_certificate, HashAlgorithmName.SHA256);

                var signatureProvider = new X509SignatureProvider(timestampProvider: null);

                Signer = new Signer(Package, signatureProvider);
            }
Esempio n. 20
0
        private static async Task AddSignatureToPackageAsync(ISignedPackage package, SignPackageRequest request, ILogger logger)
        {
            var testSignatureProvider = new X509SignatureProvider(timestampProvider: null);

            var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None);

            var base64ZipArchiveHash = Convert.ToBase64String(zipArchiveHash);
            var signatureContent     = new SignatureContent(SigningSpecifications.V1, request.SignatureHashAlgorithm, base64ZipArchiveHash);

            var signature = await testSignatureProvider.CreatePrimarySignatureAsync(request, signatureContent, logger, CancellationToken.None);

            using (var stream = new MemoryStream(signature.GetBytes()))
            {
#if IS_DESKTOP
                await package.AddSignatureAsync(stream, CancellationToken.None);
#endif
            }
        }
        private static async Task AddSignatureAndUpdatePackageAsync(
            ILogger logger,
            ISignatureProvider signatureProvider,
            SignPackageRequest 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);
        }
Esempio n. 22
0
        private static void VerifyAttributesRepository(
            CryptographicAttributeObjectCollection attributes,
            SignPackageRequest request,
            Uri v3ServiceIndexUrl,
            IReadOnlyList <string> packageOwners)
        {
            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(v3ServiceIndexUrl.OriginalString, nugetV3ServiceIndexUrl.V3ServiceIndexUrl.OriginalString);

                    nugetV3ServiceIndexUrlAttributeFound = true;
                    break;

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

                    Assert.Equal(packageOwners, nugetPackageOwners.PackageOwners);

                    nugetPackageOwnersAttributeFound = true;
                    break;
                }
            }

            Assert.True(nugetV3ServiceIndexUrlAttributeFound);
            Assert.Equal(packageOwners != null && packageOwners.Count > 0, nugetPackageOwnersAttributeFound);
        }
Esempio n. 23
0
        public async Task <Signature> CreateSignatureAsync(SignPackageRequest request, SignatureManifest signatureManifest, ILogger logger, CancellationToken token)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (signatureManifest == null)
            {
                throw new ArgumentNullException(nameof(signatureManifest));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            var authorSignature = CreateKeyVaultSignature(request.Certificate, signatureManifest);
            var timestamped     = await TimestampSignature(request, logger, authorSignature, token);

            return(timestamped);
        }
Esempio n. 24
0
        public SignPackageRequest GetSignRequest()
        {
            ValidatePackagePath();
            WarnIfNoTimestamper(Console);
            ValidateCertificateInputs();
            EnsureOutputDirectory();

            var signingSpec            = SigningSpecifications.V1;
            var signatureHashAlgorithm = ValidateAndParseHashAlgorithm(HashAlgorithm, nameof(HashAlgorithm), signingSpec);
            var timestampHashAlgorithm = ValidateAndParseHashAlgorithm(TimestampHashAlgorithm, nameof(TimestampHashAlgorithm), signingSpec);
            var certCollection         = GetCertificateCollection();
            var certificate            = GetCertificate(certCollection);
            var privateKey             = GetPrivateKey(certificate);

            var request = new SignPackageRequest(
                certificate,
                signatureHashAlgorithm,
                timestampHashAlgorithm);

            request.PrivateKey = privateKey;
            request.AdditionalCertificates.AddRange(certCollection);

            return(request);
        }
        /// <summary>
        /// Timestamps a signature for tests.
        /// </summary>
        /// <param name="timestampProvider">Timestamp provider.</param>
        /// <param name="signatureRequest">SignPackageRequest containing metadata for timestamp request.</param>
        /// <param name="signature">Signature that needs to be timestamped.</param>
        /// <param name="logger">ILogger.</param>
        /// <returns>Timestamped Signature.</returns>
        public static Task <Signature> TimestampSignature(ITimestampProvider timestampProvider, SignPackageRequest signatureRequest, Signature signature, ILogger logger)
        {
            var timestampRequest = new TimestampRequest
            {
                SignatureValue         = signature.GetBytes(),
                SigningSpec            = SigningSpecifications.V1,
                TimestampHashAlgorithm = signatureRequest.TimestampHashAlgorithm
            };

            return(TimestampSignature(timestampProvider, timestampRequest, signature, logger));
        }
        /// <summary>
        /// Generates a Signature for a given package for tests.
        /// </summary>
        /// <param name="signatureProvider">Signature proivider to create the signature.</param>
        /// <param name="package">Package to be used for the signature.</param>
        /// <param name="request">SignPackageRequest containing the metadata for the signature request.</param>
        /// <param name="testLogger">ILogger.</param>
        /// <returns>Signature for the package.</returns>
        public static async Task <Signature> CreateSignatureForPackageAsync(ISignatureProvider signatureProvider, PackageArchiveReader package, SignPackageRequest request, TestLogger testLogger)
        {
            var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None);

            var base64ZipArchiveHash = Convert.ToBase64String(zipArchiveHash);
            var signatureContent     = new SignatureContent(SigningSpecifications.V1, request.SignatureHashAlgorithm, base64ZipArchiveHash);

            return(await signatureProvider.CreateSignatureAsync(request, signatureContent, testLogger, CancellationToken.None));
        }
Esempio n. 27
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);
        }
Esempio n. 28
0
        public async Task <int> ExecuteCommandAsync(
            IEnumerable <string> packagesToSign,
            SignPackageRequest signPackageRequest,
            string timestamper,
            ILogger logger,
            string outputDirectory,
            bool overwrite,
            CancellationToken token)
        {
            var success = true;

            try
            {
                SigningUtility.Verify(signPackageRequest, logger);
            }
            catch (Exception e)
            {
                success = false;
                ExceptionUtilities.LogException(e, logger);
            }

            if (success)
            {
                var signatureProvider = GetSignatureProvider(timestamper);

                foreach (var packagePath in packagesToSign)
                {
                    // Set the output of the signing operation to a temp file because signing cannot be done in place.
                    var tempPackageFile = new FileInfo(Path.GetTempFileName());

                    try
                    {
                        string outputPath;

                        if (string.IsNullOrEmpty(outputDirectory))
                        {
                            outputPath = packagePath;
                        }
                        else
                        {
                            outputPath = Path.Combine(outputDirectory, Path.GetFileName(packagePath));
                        }

                        using (var options = SigningOptions.CreateFromFilePaths(
                                   packagePath,
                                   tempPackageFile.FullName,
                                   overwrite,
                                   signatureProvider,
                                   logger))
                        {
                            await SigningUtility.SignAsync(options, signPackageRequest, token);
                        }

                        if (tempPackageFile.Length > 0)
                        {
                            FileUtility.Replace(tempPackageFile.FullName, outputPath);
                        }
                        else
                        {
                            throw new SignatureException(Strings.Error_UnableToSignPackage);
                        }
                    }
                    catch (Exception e)
                    {
                        success = false;
                        ExceptionUtilities.LogException(e, logger);
                    }
                    finally
                    {
                        FileUtility.Delete(tempPackageFile.FullName);
                    }
                }
            }

            if (success)
            {
                logger.LogInformation(Strings.SignCommandSuccess);
            }

            return(success ? 0 : 1);
        }
        PrimarySignature CreateKeyVaultRepositoryCountersignature(CmsSigner cmsSigner, SignPackageRequest request, PrimarySignature primarySignature)
        {
            var cms = new SignedCms();

            cms.Decode(primarySignature.GetBytes());

            try
            {
                cms.SignerInfos[0].ComputeCounterSignature(cmsSigner);
            }
            catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT)
            {
                var exceptionBuilder = new StringBuilder();

                exceptionBuilder.AppendLine("Invalid provider type");
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, NuGet.Common.HashAlgorithmName.SHA256));

                throw new SignatureException(NuGetLogCode.NU3001, exceptionBuilder.ToString());
            }

            return(PrimarySignature.Load(cms));
        }
Esempio n. 30
0
        /// <summary>
        /// Timestamps a signature for tests.
        /// </summary>
        /// <param name="timestampProvider">Timestamp provider.</param>
        /// <param name="signatureRequest">SignPackageRequest containing metadata for timestamp request.</param>
        /// <param name="signature">Signature that needs to be timestamped.</param>
        /// <param name="logger">ILogger.</param>
        /// <returns>Timestamped Signature.</returns>
        public static Task <PrimarySignature> TimestampPrimarySignature(ITimestampProvider timestampProvider, SignPackageRequest signatureRequest, PrimarySignature signature, ILogger logger)
        {
            var signatureValue = signature.GetSignatureValue();
            var messageHash    = signatureRequest.TimestampHashAlgorithm.ComputeHash(signatureValue);

            var timestampRequest = new TimestampRequest(
                signingSpecifications: SigningSpecifications.V1,
                hashedMessage: messageHash,
                hashAlgorithm: signatureRequest.TimestampHashAlgorithm,
                target: SignaturePlacement.PrimarySignature
                );

            return(TimestampPrimarySignature(timestampProvider, timestampRequest, signature, logger));
        }