private async Task <TimestampResult> BouncyCastleTimeStamp(Uri timestampServer, HashAlgorithmName timestampAlgorithm, TimestampNonceFactory nonce)
        {
            var oid = HashAlgorithmTranslator.TranslateFromNameToOid(timestampAlgorithm);
            var requestGenerator = new TimeStampRequestGenerator();

            var(signatureDocument, timestampSubject) = GetSignatureToTimestamp(_part);
            using (var hash = HashAlgorithmTranslator.TranslateFromNameToxmlDSigUri(timestampAlgorithm, out _))
            {
                var digest         = hash.ComputeHash(timestampSubject);
                var request        = requestGenerator.Generate(oid.Value, digest, new Org.BouncyCastle.Math.BigInteger(nonce.Nonce));
                var encodedRequest = request.GetEncoded();
                var client         = new HttpClient();
                var content        = new ByteArrayContent(encodedRequest);
                content.Headers.Add("Content-Type", "application/timestamp-query");
                var post = await client.PostAsync(timestampServer, content);

                if (post.StatusCode != HttpStatusCode.OK)
                {
                    return(TimestampResult.Failed);
                }
                var responseBytes = await post.Content.ReadAsByteArrayAsync();

                var responseParser    = new Asn1StreamParser(responseBytes);
                var timeStampResponse = new TimeStampResponse(responseBytes);
                var tokenResponse     = timeStampResponse.TimeStampToken.GetEncoded();
                ApplyTimestamp(signatureDocument, _part, tokenResponse);
                return(TimestampResult.Success);
            }
        }
        private Task <TimestampResult> Win32TimeStamp(Uri timestampServer, HashAlgorithmName timestampAlgorithm, TimestampNonceFactory nonce)
        {
            var oid        = HashAlgorithmTranslator.TranslateFromNameToOid(timestampAlgorithm);
            var parameters = new CRYPT_TIMESTAMP_PARA
            {
                cExtension    = 0,
                fRequestCerts = true
            };

            parameters.Nonce.cbData   = nonce.Size;
            parameters.Nonce.pbData   = nonce.NoncePointer;
            parameters.pszTSAPolicyId = null;
            var(signatureDocument, timestampSubject) = GetSignatureToTimestamp(_part);
            var winResult = Crypt32.CryptRetrieveTimeStamp(
                timestampServer.AbsoluteUri,
                CryptRetrieveTimeStampRetrievalFlags.NONE,
                (uint)Timeout.TotalMilliseconds,
                oid.Value,
                ref parameters,
                timestampSubject,
                (uint)timestampSubject.Length,
                out var context,
                IntPtr.Zero,
                IntPtr.Zero
                );

            if (!winResult)
            {
                return(Task.FromResult(TimestampResult.Failed));
            }
            using (context)
            {
                var refSuccess = false;
                try
                {
                    context.DangerousAddRef(ref refSuccess);
                    if (!refSuccess)
                    {
                        return(Task.FromResult(TimestampResult.Failed));
                    }
                    var structure = Marshal.PtrToStructure <CRYPT_TIMESTAMP_CONTEXT>(context.DangerousGetHandle());
                    var encoded   = new byte[structure.cbEncoded];
                    Marshal.Copy(structure.pbEncoded, encoded, 0, encoded.Length);
                    ApplyTimestamp(signatureDocument, _part, encoded);
                    return(Task.FromResult(TimestampResult.Success));
                }
                finally
                {
                    if (refSuccess)
                    {
                        context.DangerousRelease();
                    }
                }
            }
        }