示例#1
0
        public void ShouldTimestampData()
        {
            var data       = new byte[] { 1, 2, 3 };
            var parameters = new CRYPT_TIMESTAMP_PARA
            {
                cExtension     = 0,
                fRequestCerts  = true,
                pszTSAPolicyId = null
            };

            var ok = Crypt32.CryptRetrieveTimeStamp("http://timestamp.digicert.com", CryptRetrieveTimeStampRetrievalFlags.NONE, 30 * 1000, "1.3.14.3.2.26", ref parameters, data, (uint)data.Length, out var pointer, IntPtr.Zero, IntPtr.Zero);

            Assert.True(ok);
            bool success = false;

            try
            {
                pointer.DangerousAddRef(ref success);
                Assert.True(success);
                var structure = Marshal.PtrToStructure <CRYPT_TIMESTAMP_CONTEXT>(pointer.DangerousGetHandle());
                var encoded   = new byte[structure.cbEncoded];
                Marshal.Copy(structure.pbEncoded, encoded, 0, encoded.Length);
            }
            finally
            {
                if (success)
                {
                    pointer.DangerousRelease();
                }
            }
        }
        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();
                    }
                }
            }
        }
示例#3
0
        private static unsafe Task <(TimestampResult, byte[])> SubmitTimestampRequest(Uri timestampUri, Oid digestOid, TimestampNonce nonce, TimeSpan timeout, byte[] digest)
        {
            var parameters = new CRYPT_TIMESTAMP_PARA
            {
                cExtension    = 0,
                fRequestCerts = true
            };

            using (var cNonce = nonce.Nonce.Pin())
            {
                parameters.Nonce.cbData   = (uint)nonce.Nonce.Length;
                parameters.Nonce.pbData   = new IntPtr(cNonce.Pointer);
                parameters.pszTSAPolicyId = null;
                var winResult = Crypt32.CryptRetrieveTimeStamp(
                    timestampUri.AbsoluteUri,
                    CryptRetrieveTimeStampRetrievalFlags.TIMESTAMP_DONT_HASH_DATA,
                    (uint)timeout.TotalMilliseconds,
                    digestOid.Value,
                    ref parameters,
                    digest,
                    (uint)digest.Length,
                    out var context,
                    IntPtr.Zero,
                    IntPtr.Zero
                    );
                if (!winResult)
                {
                    return(Task.FromResult <(TimestampResult, byte[])>((TimestampResult.Failed, null)));
                }
                using (context)
                {
                    var refSuccess = false;
                    try
                    {
                        context.DangerousAddRef(ref refSuccess);
                        if (!refSuccess)
                        {
                            return(Task.FromResult <(TimestampResult, byte[])>((TimestampResult.Failed, null)));
                        }
                        var structure = Marshal.PtrToStructure <CRYPT_TIMESTAMP_CONTEXT>(context.DangerousGetHandle());
                        var encoded   = new byte[structure.cbEncoded];
                        Marshal.Copy(structure.pbEncoded, encoded, 0, encoded.Length);
                        return(Task.FromResult <(TimestampResult, byte[])>((TimestampResult.Success, encoded)));
                    }
                    finally
                    {
                        if (refSuccess)
                        {
                            context.DangerousRelease();
                        }
                    }
                }
            }
        }
 internal static extern bool CryptRetrieveTimeStamp(
     [MarshalAs(UnmanagedType.LPWStr)] string wszUrl,
     CryptRetrieveTimeStampFlags dwRetrievalFlags,
     int dwTimeout,
     [MarshalAs(UnmanagedType.LPStr)] string pszHashId,
     ref CRYPT_TIMESTAMP_PARA pPara,
     [In] byte[] pbData,
     int cbData,
     ref IntPtr ppTsContext,
     ref IntPtr ppTsSigner,
     ref IntPtr phStore);