public unsafe IRfc3161TimestampToken SubmitRequest(Uri timestampUri, TimeSpan timeout)
        {
            if (timestampUri == null)
            {
                throw new ArgumentNullException(nameof(timestampUri));
            }
            if (!timestampUri.IsAbsoluteUri)
            {
                throw new ArgumentException("Absolute URI required", nameof(timestampUri));
            }
            if (timestampUri.Scheme != Uri.UriSchemeHttp && timestampUri.Scheme != Uri.UriSchemeHttps)
            {
                throw new ArgumentException("HTTP/HTTPS required", nameof(timestampUri));
            }

            IntPtr requestedPolicyPtr = IntPtr.Zero;
            IntPtr pTsContext         = IntPtr.Zero;
            IntPtr pTsSigner          = IntPtr.Zero;
            IntPtr hStore             = IntPtr.Zero;

            const Rfc3161TimestampWin32.CryptRetrieveTimeStampFlags flags =
                Rfc3161TimestampWin32.CryptRetrieveTimeStampFlags.TIMESTAMP_VERIFY_CONTEXT_SIGNATURE |
                Rfc3161TimestampWin32.CryptRetrieveTimeStampFlags.TIMESTAMP_DONT_HASH_DATA;

            try
            {
                requestedPolicyPtr = Marshal.StringToHGlobalAnsi(Data._requestedPolicyId?.Value);

                Rfc3161TimestampWin32.CRYPT_TIMESTAMP_PARA para = new Rfc3161TimestampWin32.CRYPT_TIMESTAMP_PARA()
                {
                    fRequestCerts  = Data._requestSignerCertificate,
                    pszTSAPolicyId = requestedPolicyPtr,
                };

                if (Data._extensions?.Count > 0)
                {
                    throw new NotImplementedException();

                    fixed(byte *pbNonce = Data._nonce)
                    {
                        if (Data._nonce != null)
                        {
                            para.Nonce.cbData = (uint)Data._nonce.Length;
                            para.Nonce.pbData = (IntPtr)pbNonce;
                        }

                        if (!Rfc3161TimestampWin32.CryptRetrieveTimeStamp(
                                timestampUri.AbsoluteUri,
                                flags,
                                (int)timeout.TotalMilliseconds,
                                Data._hashAlgorithm.Value,
                                ref para,
                                Data._hash,
                                Data._hash.Length,
                                ref pTsContext,
                                ref pTsSigner,
                                ref hStore))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }
                    }

                    var content    = (Rfc3161TimestampWin32.CRYPT_TIMESTAMP_CONTEXT)Marshal.PtrToStructure(pTsContext, typeof(Rfc3161TimestampWin32.CRYPT_TIMESTAMP_CONTEXT));
                    byte[] encoded = new byte[content.cbEncoded];
                    Marshal.Copy(content.pbEncoded, encoded, 0, content.cbEncoded);

                    var tstInfo = new Rfc3161TimestampTokenInfoNet472Wrapper(new Rfc3161TimestampTokenInfo(pTsContext));
                    X509Certificate2 signerCert = new X509Certificate2(pTsSigner);

                    using (X509Store extraCerts = new X509Store(hStore))
                    {
                        X509Certificate2Collection additionalCertsColl = new X509Certificate2Collection();

                        foreach (var cert in extraCerts.Certificates)
                        {
                            if (!signerCert.Equals(cert))
                            {
                                additionalCertsColl.Add(cert);
                            }
                        }

                        return(Rfc3161TimestampTokenFactory.Create(
                                   tstInfo,
                                   signerCert,
                                   additionalCertsColl,
                                   encoded));
                    }
            }
            finally
            {
                if (hStore != IntPtr.Zero)
                {
                    Rfc3161TimestampWin32.CertCloseStore(hStore, 0);
                }

                if (pTsSigner != IntPtr.Zero)
                {
                    Rfc3161TimestampWin32.CertFreeCertificateContext(pTsSigner);
                }

                if (pTsContext != IntPtr.Zero)
                {
                    Rfc3161TimestampWin32.CryptMemFree(pTsContext);
                }

                if (requestedPolicyPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(requestedPolicyPtr);
                }
            }
        }
Ejemplo n.º 2
0
        private static Rfc3161TimestampToken CryptVerifyTimeStampSignature(byte[] encodedToken, byte[] data)
        {
            IntPtr pTsContext = IntPtr.Zero;
            IntPtr pTsSigner  = IntPtr.Zero;
            IntPtr hStore     = IntPtr.Zero;

            try
            {
                if (!Rfc3161TimestampWin32.CryptVerifyTimeStampSignature(
                        encodedToken,
                        encodedToken.Length,
                        data,
                        data?.Length ?? 0,
                        IntPtr.Zero,
                        ref pTsContext,
                        ref pTsSigner,
                        ref hStore))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }

                IRfc3161TimestampTokenInfo tstInfo    = new Rfc3161TimestampTokenInfoNet472Wrapper(new Rfc3161TimestampTokenInfo(pTsContext));
                X509Certificate2           signerCert = new X509Certificate2(pTsSigner);

                using (X509Store extraCerts = new X509Store(hStore))
                {
                    X509Certificate2Collection additionalCertsColl = new X509Certificate2Collection();

                    foreach (var cert in extraCerts.Certificates)
                    {
                        if (!signerCert.Equals(cert))
                        {
                            additionalCertsColl.Add(cert);
                        }
                    }

                    return(new Rfc3161TimestampToken(
                               tstInfo,
                               signerCert,
                               additionalCertsColl,
                               (byte[])encodedToken.Clone()));
                }
            }
            finally
            {
                if (pTsContext != IntPtr.Zero)
                {
                    Rfc3161TimestampWin32.CryptMemFree(pTsContext);
                }

                if (pTsSigner != IntPtr.Zero)
                {
                    Rfc3161TimestampWin32.CertFreeCertificateContext(pTsSigner);
                }

                if (hStore != IntPtr.Zero)
                {
                    Rfc3161TimestampWin32.CertCloseStore(hStore, 0);
                }
            }
        }