/// <summary>
        /// Creates a signature from the enqueued parts.
        /// </summary>
        /// <param name="configuration">The configuration of properties used to create the signature.
        /// See the documented of <see cref="CertificateSignConfigurationSet"/> for more information.</param>
        public async Task <OpcSignature> SignAsync(CertificateSignConfigurationSet configuration)
        {
            var fileName = configuration.SigningCertificate.GetCertHashString() + ".psdsxs";

            var(allParts, signatureFile) = SignCore(fileName);
            using (var signingContext = new CertificateSigningContext(configuration.SigningCertificate, configuration.PkcsDigestAlgorithm, configuration.FileDigestAlgorithm))
            {
                var fileManifest = OpcSignatureManifest.Build(signingContext, allParts);
                var builder      = new XmlSignatureBuilder(signingContext);
                builder.SetFileManifest(fileManifest);
                var result = await builder.BuildAsync();

                PublishSignature(result, signatureFile);
            }
            _package.Flush();
            return(new OpcSignature(signatureFile));
        }
        /// <summary>
        /// Creates a new signing context.
        /// </summary>
        /// <param name="certificate">The certificate for signing and verifying data.</param>
        /// <param name="pkcsHashAlgorithmName">
        /// A hash algorithm. Currently, this is used in the PKCS#1 padding operation with RSA. The value is ignored for
        /// ECC signatures. This should usually match the algorithm used to hash the data that will be signed and verified.
        /// </param>
        /// <param name="fileDigestAlgorithmName">
        /// A hash algorithm. This is the digest algorting used for digesting files.
        /// </param>
        public CertificateSigningContext(CertificateSignConfigurationSet configuration)
        {
            Certificate             = configuration.SigningCertificate;
            ContextCreationTime     = DateTimeOffset.Now;
            _pkcsHashAlgorithmName  = configuration.PkcsDigestAlgorithm;
            FileDigestAlgorithmName = configuration.FileDigestAlgorithm;
            switch (Certificate.PublicKey.Oid.Value)
            {
            case KnownOids.X509Algorithms.RSA:
                SignatureAlgorithm = SigningAlgorithm.RSA;
                _signProvider      = new RSAPkcsCertificateSign(Certificate);
                break;

            case KnownOids.X509Algorithms.Ecc:
                SignatureAlgorithm = SigningAlgorithm.ECDSA;
                _signProvider      = new ECDsaCertificateSign(Certificate);
                break;

            default:
                throw new NotSupportedException("The specified signature algorithm is not supported.");
            }
        }
 /// <summary>
 /// Creates a signature from the enqueued parts.
 /// </summary>
 /// <param name="configuration">The configuration of properties used to create the signature.
 /// See the documented of <see cref="CertificateSignConfigurationSet"/> for more information.</param>
 public Task <OpcSignature> SignAsync(CertificateSignConfigurationSet configuration)
 {
     return(SignAsyncImpl <CertificateSignConfigurationSet, CertificateSigningContext>(configuration));
 }