Example #1
0
        /// <summary>
        /// SignedCms containing a time stamp authority token reponse
        /// </summary>
        /// <param name="timestampCms">SignedCms from Time Stamp Authority</param>
        public Timestamp(SignedCms timestampCms)
        {
            SignedCms = timestampCms ?? throw new ArgumentNullException(nameof(timestampCms));

            if (Rfc3161TimestampVerificationUtility.TryReadTSTInfoFromSignedCms(timestampCms, out var tstInfo))
            {
                try
                {
                    SignedCms.CheckSignature(verifySignatureOnly: true);
                }
                catch (Exception ex)
                {
                    throw new TimestampException(NuGetLogCode.NU3021, Strings.VerifyError_TimestampSignatureValidationFailed, ex);
                }

                TstInfo         = tstInfo;
                GeneralizedTime = tstInfo.Timestamp;

                var accuracyInMilliseconds = Rfc3161TimestampVerificationUtility.GetAccuracyInMilliseconds(tstInfo);
                UpperLimit = tstInfo.Timestamp.AddMilliseconds(accuracyInMilliseconds);
                LowerLimit = tstInfo.Timestamp.AddMilliseconds(-accuracyInMilliseconds);
            }
            else
            {
                throw new TimestampException(NuGetLogCode.NU3021, Strings.VerifyError_TimestampSignatureValidationFailed);
            }
        }
Example #2
0
        internal static double GetAccuracyInMilliseconds(Rfc3161TimestampTokenInfo tstInfo)
        {
            double accuracyInMilliseconds;

            if (!tstInfo.AccuracyInMicroseconds.HasValue)
            {
                if (StringComparer.Ordinal.Equals(tstInfo.PolicyId, Oids.BaselineTimestampPolicy))
                {
                    accuracyInMilliseconds = 1000;
                }
                else
                {
                    accuracyInMilliseconds = 0;
                }
            }
            else
            {
                accuracyInMilliseconds = tstInfo.AccuracyInMicroseconds.Value * _millisecondsPerMicrosecond;
            }

            if (accuracyInMilliseconds < 0)
            {
                throw new InvalidDataException(Strings.TimestampInvalid);
            }

            return(accuracyInMilliseconds);
        }
        public Rfc3161TimestampRequest(
            byte[] messageHash,
            HashAlgorithmName hashAlgorithm,
            Oid requestedPolicyId              = null,
            byte[] nonce                       = null,
            bool requestSignerCertificates     = false,
            X509ExtensionCollection extensions = null)
        {
            if (messageHash == null)
            {
                throw new ArgumentNullException(nameof(messageHash));
            }

            int    expectedSize;
            string algorithmIdentifier;

            if (!ResolveAlgorithm(hashAlgorithm, out expectedSize, out algorithmIdentifier))
            {
                throw new ArgumentOutOfRangeException(
                          nameof(hashAlgorithm),
                          hashAlgorithm,
                          "Hash algorithm is not supported by this method");
            }

            if (messageHash.Length != expectedSize)
            {
                throw new ArgumentException("Hash is not the correct size for the identified algorithm", nameof(messageHash));
            }

            if (requestedPolicyId != null && !Rfc3161TimestampUtils.IsLegalOid(requestedPolicyId.Value))
            {
                throw new ArgumentException("Value is not a legal object identifier", nameof(requestedPolicyId));
            }

            if (nonce != null && nonce.Length == 0)
            {
                throw new ArgumentException("Nonce must be null or non-empty", nameof(nonce));
            }

            var data = new DataType
            {
                _version                  = 1,
                _hash                     = (byte[])messageHash.Clone(),
                _hashAlgorithm            = OpportunisticOid(algorithmIdentifier),
                _nonce                    = (byte[])nonce?.Clone(),
                _requestSignerCertificate = requestSignerCertificates,
                _extensions               = Rfc3161TimestampTokenInfo.ShallowCopy(extensions, preserveNull: true),
            };

            if (requestedPolicyId != null)
            {
                data._requestedPolicyId = new Oid(requestedPolicyId.Value, requestedPolicyId.FriendlyName);
            }

            RawData = Encode(data);
        }
Example #4
0
 internal static bool TryReadTSTInfoFromSignedCms(
     SignedCms timestampCms,
     out Rfc3161TimestampTokenInfo tstInfo)
 {
     tstInfo = null;
     if (timestampCms.ContentInfo.ContentType.Value.Equals(Oids.TSTInfoContentType))
     {
         tstInfo = new Rfc3161TimestampTokenInfo(timestampCms.ContentInfo.Content);
         return(true);
     }
     // return false if the signedCms object does not contain the right ContentType
     return(false);
 }
        public Rfc3161TimestampRequest(
            byte[] messageHash,
            Oid hashAlgorithmId,
            Oid requestedPolicyId              = null,
            byte[] nonce                       = null,
            bool requestSignerCertificates     = false,
            X509ExtensionCollection extensions = null)
        {
            if (messageHash == null)
            {
                throw new ArgumentNullException(nameof(messageHash));
            }
            if (hashAlgorithmId == null)
            {
                throw new ArgumentNullException(nameof(hashAlgorithmId));
            }
            if (!Rfc3161TimestampUtils.IsLegalOid(hashAlgorithmId.Value))
            {
                throw new ArgumentException("Value is not a legal object identifier", nameof(hashAlgorithmId));
            }

            if (requestedPolicyId != null && !Rfc3161TimestampUtils.IsLegalOid(requestedPolicyId.Value))
            {
                throw new ArgumentException("Value is not a legal object identifier", nameof(requestedPolicyId));
            }

            if (nonce != null && nonce.Length == 0)
            {
                throw new ArgumentException("Nonce must be null or non-empty", nameof(nonce));
            }

            DataType data = new DataType
            {
                _version                  = 1,
                _hash                     = (byte[])messageHash.Clone(),
                _hashAlgorithm            = new Oid(hashAlgorithmId.Value, hashAlgorithmId.FriendlyName),
                _nonce                    = (byte[])nonce?.Clone(),
                _requestSignerCertificate = requestSignerCertificates,
                _extensions               = Rfc3161TimestampTokenInfo.ShallowCopy(extensions, preserveNull: true),
            };

            if (requestedPolicyId != null)
            {
                data._requestedPolicyId = new Oid(requestedPolicyId.Value, requestedPolicyId.FriendlyName);
            }

            _data   = data;
            RawData = Encode(data);
        }
        internal Rfc3161TimestampToken(
            Rfc3161TimestampTokenInfo tstInfo,
            X509Certificate2 signerCertificate,
            X509Certificate2Collection additionalCerts,
            byte[] encoded)
        {
            Debug.Assert(tstInfo != null);
            Debug.Assert(signerCertificate != null);
            Debug.Assert(additionalCerts != null);

            TokenInfo         = tstInfo;
            SignerCertificate = signerCertificate;
            AdditionalCerts   = additionalCerts;
            _encoded          = encoded;
        }
        internal static bool ValidateSignerCertificateAgainstTimestamp(
            X509Certificate2 signerCertificate,
            Rfc3161TimestampTokenInfo tstInfo)
        {
            var tstInfoGenTime         = tstInfo.Timestamp;
            var accuracyInMilliseconds = GetAccuracyInMilliseconds(tstInfo);

            var timestampUpperGenTime = tstInfoGenTime.AddMilliseconds(accuracyInMilliseconds);
            var timestampLowerGenTime = tstInfoGenTime.Subtract(TimeSpan.FromMilliseconds(accuracyInMilliseconds));

            DateTimeOffset signerCertExpiry = DateTime.SpecifyKind(signerCertificate.NotAfter, DateTimeKind.Local);
            DateTimeOffset signerCertBegin  = DateTime.SpecifyKind(signerCertificate.NotBefore, DateTimeKind.Local);

            return(timestampUpperGenTime < signerCertExpiry &&
                   timestampLowerGenTime > signerCertBegin);
        }
 public Rfc3161TimestampTokenInfoNet472Wrapper(Rfc3161TimestampTokenInfo timestampTokenInfo)
 {
     _rfc3161TimestampTokenInfo = timestampTokenInfo;
 }
 public Rfc3161TimestampTokenInfoNet472Wrapper(byte[] timestampTokenInfo)
 {
     _rfc3161TimestampTokenInfo = new Rfc3161TimestampTokenInfo(timestampTokenInfo);
 }
 public X509ExtensionCollection GetExtensions() =>
 Rfc3161TimestampTokenInfo.ShallowCopy(Data._extensions, preserveNull: false);
        private static Rfc3161TimestampToken CryptVerifyTimeStampSignature(byte[] encodedToken, byte[] data)
        {
            var pTsContext = IntPtr.Zero;
            var pTsSigner  = IntPtr.Zero;
            var 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());
                }

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

                using (var extraCerts = new X509Store(hStore))
                {
                    var 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);
                }
            }
        }
Example #12
0
        public unsafe Rfc3161TimestampToken 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);

                    Rfc3161TimestampTokenInfo tstInfo = 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,
                                   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);
                }
            }
        }