コード例 #1
0
        public static void Verify(SignPackageRequest request, ILogger logger)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

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

            if (!CertificateUtility.IsSignatureAlgorithmSupported(request.Certificate))
            {
                throw new SignatureException(NuGetLogCode.NU3013, Strings.SigningCertificateHasUnsupportedSignatureAlgorithm);
            }

            if (!CertificateUtility.IsCertificatePublicKeyValid(request.Certificate))
            {
                throw new SignatureException(NuGetLogCode.NU3014, Strings.SigningCertificateFailsPublicKeyLengthRequirement);
            }

            if (CertificateUtility.HasExtendedKeyUsage(request.Certificate, Oids.LifetimeSigningEku))
            {
                throw new SignatureException(NuGetLogCode.NU3015, Strings.ErrorCertificateHasLifetimeSigningEKU);
            }

            if (CertificateUtility.IsCertificateValidityPeriodInTheFuture(request.Certificate))
            {
                throw new SignatureException(NuGetLogCode.NU3017, Strings.SignatureNotYetValid);
            }

            request.BuildSigningCertificateChainOnce(logger);
        }
コード例 #2
0
        public static CryptographicAttributeObjectCollection CreateSignedAttributes(
            SignPackageRequest request,
            IReadOnlyList <X509Certificate2> chainList)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (chainList == null || chainList.Count == 0)
            {
                throw new ArgumentException(Strings.ArgumentCannotBeNullOrEmpty, nameof(chainList));
            }

            var attributes = new CryptographicAttributeObjectCollection
            {
                new Pkcs9SigningTime()
            };

            if (request.SignatureType != SignatureType.Unknown)
            {
                // Add signature type if set.
                attributes.Add(AttributeUtility.CreateCommitmentTypeIndication(request.SignatureType));
            }

            attributes.Add(AttributeUtility.CreateSigningCertificateV2(chainList[0], request.SignatureHashAlgorithm));

            return(attributes);
        }
コード例 #3
0
        private Signature CreateSignature(SignPackageRequest request, SignatureContent signatureContent)
        {
            var cmsSigner = CreateCmsSigner(request);

            if (request.PrivateKey != null)
            {
                return(CreateSignature(cmsSigner, signatureContent, request.PrivateKey));
            }

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

            try
            {
                cms.ComputeSignature(cmsSigner);
            }
            catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT)
            {
                var exceptionBuilder = new StringBuilder();

                exceptionBuilder.AppendLine(Strings.SignFailureCertificateInvalidProviderType);
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate));

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

            return(Signature.Load(cms));
        }
コード例 #4
0
        private static PrimarySignature CreatePrimarySignature(CmsSigner cmsSigner, SignPackageRequest request, byte[] signingData)
        {
            var contentInfo = new ContentInfo(signingData);
            var cms         = new SignedCms(contentInfo);

            try
            {
#if IS_DESKTOP
                cms.ComputeSignature(cmsSigner);
#else
                // In .NET Framework, this parameter is not used and a PIN prompt is always shown. In .NET Core, the silent flag needs to be set to false to show a PIN prompt.
                cms.ComputeSignature(cmsSigner, silent: false);
#endif
            }
            catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT)
            {
                var exceptionBuilder = new StringBuilder();

                exceptionBuilder.AppendLine(Strings.SignFailureCertificateInvalidProviderType);
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, Common.HashAlgorithmName.SHA256));

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

            return(PrimarySignature.Load(cms));
        }
コード例 #5
0
        /// <summary>
        /// Sign the package stream hash with an X509Certificate2.
        /// </summary>
        public 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));
            }

            var signature = CreatePrimarySignature(request, signatureContent, logger);

            if (_timestampProvider == null)
            {
                return(Task.FromResult(signature));
            }
            else
            {
                return(TimestampPrimarySignatureAsync(request, logger, signature, token));
            }
        }
コード例 #6
0
        /// <summary>
        /// Add a signature to a package.
        /// </summary>
        public async Task SignAsync(SignPackageRequest request, ILogger logger, CancellationToken token)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

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

            token.ThrowIfCancellationRequested();

            if (await _package.IsZip64Async(token))
            {
                throw new SignatureException(NuGetLogCode.NU3006, Strings.ErrorZip64NotSupported);
            }

            SigningUtility.Verify(request);

            var zipArchiveHash = await _package.GetArchiveHashAsync(request.SignatureHashAlgorithm, token);

            var signatureContent = GenerateSignatureContent(request.SignatureHashAlgorithm, zipArchiveHash);
            var signature        = await _signatureProvider.CreateSignatureAsync(request, signatureContent, logger, token);

            using (var stream = new MemoryStream(signature.GetBytes()))
            {
                await _package.AddSignatureAsync(stream, token);
            }
        }
コード例 #7
0
        public static CmsSigner CreateCmsSigner(SignPackageRequest request, 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);
            }
            else
            {
                signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, request.Certificate);
            }

            request.BuildSigningCertificateChainOnce(logger);

            var chain = request.Chain;

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

            CryptographicAttributeObjectCollection attributes;

            if (request.SignatureType == SignatureType.Repository)
            {
                attributes = CreateSignedAttributes((RepositorySignPackageRequest)request, chain);
            }
            else
            {
                attributes = 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);
        }
コード例 #8
0
        private static PrimarySignature CreateRepositoryCountersignature(SignPackageRequest request, PrimarySignature primarySignature, ILogger logger)
        {
            var cmsSigner = SigningUtility.CreateCmsSigner(request, logger);

            if (request.PrivateKey != null)
            {
                return(CreateRepositoryCountersignature(cmsSigner, primarySignature, request.PrivateKey));
            }

            return(CreateRepositoryCountersignature(cmsSigner, request, primarySignature));
        }
コード例 #9
0
        private Task <Signature> TimestampSignature(SignPackageRequest request, ILogger logger, Signature signature, CancellationToken token)
        {
            var timestampRequest = new TimestampRequest
            {
                SignatureValue         = signature.GetBytes(),
                SigningSpec            = SigningSpecifications.V1,
                TimestampHashAlgorithm = request.TimestampHashAlgorithm
            };

            return(_timestampProvider.TimestampSignatureAsync(timestampRequest, logger, token));
        }
コード例 #10
0
        private static PrimarySignature CreatePrimarySignature(SignPackageRequest request, SignatureContent signatureContent, ILogger logger)
        {
            var cmsSigner = SigningUtility.CreateCmsSigner(request, logger);

            if (request.PrivateKey != null)
            {
                return(CreatePrimarySignature(cmsSigner, signatureContent.GetBytes(), request.PrivateKey));
            }

            return(CreatePrimarySignature(cmsSigner, request, signatureContent.GetBytes()));
        }
コード例 #11
0
        private 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));
        }
コード例 #12
0
        public static void Verify(SignPackageRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (!IsSignatureAlgorithmSupported(request.Certificate))
            {
                throw new SignatureException(NuGetLogCode.NU3013, Strings.SigningCertificateHasUnsupportedSignatureAlgorithm);
            }

            if (!IsCertificatePublicKeyValid(request.Certificate))
            {
                throw new SignatureException(NuGetLogCode.NU3014, Strings.SigningCertificateFailsPublicKeyLengthRequirement);
            }

            request.BuildCertificateChainOnce();
        }
コード例 #13
0
        public static CryptographicAttributeObjectCollection GetSignedAttributes(
            SignPackageRequest request,
            IReadOnlyList <X509Certificate2> chain)
        {
            var attributes = new CryptographicAttributeObjectCollection
            {
                new Pkcs9SigningTime()
            };

            if (request.SignatureType != SignatureType.Unknown)
            {
                // Add signature type if set.
                attributes.Add(AttributeUtility.GetCommitmentTypeIndication(request.SignatureType));
            }

            // Add the full chain of certificate hashes
            attributes.Add(AttributeUtility.GetSigningCertificateV2(chain, request.SignatureHashAlgorithm));

            return(attributes);
        }
コード例 #14
0
        private static PrimarySignature CreatePrimarySignature(CmsSigner cmsSigner, SignPackageRequest request, byte[] signingData)
        {
            var contentInfo = new ContentInfo(signingData);
            var cms         = new SignedCms(contentInfo);

            try
            {
                cms.ComputeSignature(cmsSigner);
            }
            catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT)
            {
                var exceptionBuilder = new StringBuilder();

                exceptionBuilder.AppendLine(Strings.SignFailureCertificateInvalidProviderType);
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, Common.HashAlgorithmName.SHA256));

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

            return(PrimarySignature.Load(cms));
        }
コード例 #15
0
        private static CmsSigner CreateCmsSigner(SignPackageRequest request)
        {
            // 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);
            }
            else
            {
                signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, request.Certificate);
            }

            request.BuildCertificateChainOnce();

            var chain = request.Chain;

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

            var attributes = SigningUtility.GetSignedAttributes(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);
        }
コード例 #16
0
 /// <summary>
 /// Add a signature to a package.
 /// </summary>
 public Task SignAsync(SignPackageRequest request, ILogger logger, CancellationToken token) => throw new NotImplementedException();
コード例 #17
0
        /// <summary>
        /// Add a signature to a package.
        /// </summary>
        public static async Task SignAsync(SigningOptions options, SignPackageRequest signRequest, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            Verify(signRequest, options.Logger);

            var    tempPackageFile       = new FileInfo(Path.GetTempFileName());
            Stream unsignedPackageStream = null;
            var    signaturePlacement    = SignaturePlacement.PrimarySignature;

            try
            {
                PrimarySignature primarySignature;
                var isSigned = false;

                using (var package = new SignedPackageArchive(options.InputPackageStream, Stream.Null))
                {
                    if (await package.IsZip64Async(token))
                    {
                        throw new SignatureException(NuGetLogCode.NU3006, Strings.ErrorZip64NotSupported);
                    }

                    primarySignature = await package.GetPrimarySignatureAsync(token);

                    isSigned = primarySignature != null;

                    if (signRequest.SignatureType == SignatureType.Repository && primarySignature != null)
                    {
                        if (primarySignature.Type == SignatureType.Repository)
                        {
                            throw new SignatureException(NuGetLogCode.NU3033, Strings.Error_RepositorySignatureMustNotHaveARepositoryCountersignature);
                        }

                        if (SignatureUtility.HasRepositoryCountersignature(primarySignature))
                        {
                            throw new SignatureException(NuGetLogCode.NU3032, Strings.SignedPackagePackageAlreadyCountersigned);
                        }

                        signaturePlacement = SignaturePlacement.Countersignature;
                    }

                    if (isSigned && !options.Overwrite && signaturePlacement != SignaturePlacement.Countersignature)
                    {
                        throw new SignatureException(NuGetLogCode.NU3001, Strings.SignedPackageAlreadySigned);
                    }
                }

                var inputPackageStream = options.InputPackageStream;
                if (isSigned)
                {
                    unsignedPackageStream = tempPackageFile.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite);

                    using (var package = new SignedPackageArchive(options.InputPackageStream, unsignedPackageStream))
                    {
                        await package.RemoveSignatureAsync(token);
                    }

                    inputPackageStream = unsignedPackageStream;
                }

                using (var package = new SignedPackageArchive(inputPackageStream, options.OutputPackageStream))
                {
                    PrimarySignature signature;
                    if (signaturePlacement == SignaturePlacement.Countersignature)
                    {
                        signature = await options.SignatureProvider.CreateRepositoryCountersignatureAsync(
                            signRequest as RepositorySignPackageRequest,
                            primarySignature,
                            options.Logger,
                            token);
                    }
                    else
                    {
                        var hashAlgorithm  = signRequest.SignatureHashAlgorithm;
                        var zipArchiveHash = await package.GetArchiveHashAsync(hashAlgorithm, token);

                        var signatureContent = GenerateSignatureContent(hashAlgorithm, zipArchiveHash);
                        signature = await options.SignatureProvider.CreatePrimarySignatureAsync(signRequest, signatureContent, options.Logger, token);
                    }

                    using (var stream = new MemoryStream(signature.GetBytes()))
                    {
                        await package.AddSignatureAsync(stream, token);
                    }
                }
            }
            finally
            {
                if (unsignedPackageStream != null && !ReferenceEquals(unsignedPackageStream, options.InputPackageStream))
                {
                    unsignedPackageStream.Dispose();
                }

                FileUtility.Delete(tempPackageFile.FullName);
            }
        }
コード例 #18
0
 public Task <Signature> CreateSignatureAsync(SignPackageRequest request, SignatureContent signatureContent, ILogger logger, CancellationToken token)
 {
     return(Task.FromResult(_signature));
 }
コード例 #19
0
 /// <summary>
 /// Add a signature to a package.
 /// </summary>
 public static Task SignAsync(SigningOptions options, SignPackageRequest signRequest, CancellationToken token) => throw new NotImplementedException();
コード例 #20
0
 private Task <PrimarySignature> TimestampRepositoryCountersignatureAsync(SignPackageRequest request, ILogger logger, PrimarySignature signature, CancellationToken token)
 {
     throw new NotSupportedException();
 }
コード例 #21
0
 private static PrimarySignature CreateRepositoryCountersignature(SignPackageRequest request, PrimarySignature signature, ILogger logger)
 {
     throw new NotSupportedException();
 }
コード例 #22
0
 private static PrimarySignature CreatePrimarySignature(SignPackageRequest request, SignatureContent signatureContent, ILogger logger)
 {
     throw new NotSupportedException();
 }
コード例 #23
0
        private static PrimarySignature CreateRepositoryCountersignature(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(Strings.SignFailureCertificateInvalidProviderType);
                exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, Common.HashAlgorithmName.SHA256));

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

            return(PrimarySignature.Load(cms));
        }
コード例 #24
0
 private Signature CreateSignature(SignPackageRequest request, SignatureContent signatureContent)
 {
     throw new NotSupportedException();
 }
コード例 #25
0
 private Task <Signature> TimestampSignature(SignPackageRequest request, ILogger logger, Signature signature, CancellationToken token)
 {
     throw new NotSupportedException();
 }