private static void CheckSignatures(SignerInfoCollection signers, X509Certificate2Collection extraStore, bool verifySignatureOnly)
        {
            if ((signers == null) || (signers.Count < 1))
            {
                throw new CryptographicException(-2146885618);
            }
            SignerInfoEnumerator enumerator = signers.GetEnumerator();

            while (enumerator.MoveNext())
            {
                SignerInfo current = enumerator.Current;
                current.CheckSignature(extraStore, verifySignatureOnly);
                if (current.CounterSignerInfos.Count > 0)
                {
                    CheckSignatures(current.CounterSignerInfos, extraStore, verifySignatureOnly);
                }
            }
        }
Ejemplo n.º 2
0
        private static bool CheckCertificate(
            X509Certificate2 tsaCertificate,
            SignerInfo signer,
            EssCertId certId,
            EssCertIdV2 certId2,
            Rfc3161TimestampTokenInfo tokenInfo)
        {
            Debug.Assert(tsaCertificate != null);
            Debug.Assert(signer != null);
            Debug.Assert(tokenInfo != null);
            // certId and certId2 are allowed to be null, they get checked in CertMatchesIds.

            if (!CertMatchesIds(tsaCertificate, certId, certId2))
            {
                return(false);
            }

            // Nothing in RFC3161 actually mentions checking the certificate's validity
            // against the TSTInfo timestamp value, but it seems sensible.
            //
            // Accuracy is ignored here, for better replicability in user code.

            if (tsaCertificate.NotAfter < tokenInfo.Timestamp ||
                tsaCertificate.NotBefore > tokenInfo.Timestamp)
            {
                return(false);
            }

            // https://tools.ietf.org/html/rfc3161#section-2.3
            //
            // The TSA MUST sign each time-stamp message with a key reserved
            // specifically for that purpose.  A TSA MAY have distinct private keys,
            // e.g., to accommodate different policies, different algorithms,
            // different private key sizes or to increase the performance. The
            // corresponding certificate MUST contain only one instance of the
            // extended key usage field extension as defined in [RFC2459] Section
            // 4.2.1.13 with KeyPurposeID having value:
            //
            // id-kp-timeStamping. This extension MUST be critical.

            using (var ekuExts = tsaCertificate.Extensions.OfType <X509EnhancedKeyUsageExtension>().GetEnumerator())
            {
                if (!ekuExts.MoveNext())
                {
                    return(false);
                }

                X509EnhancedKeyUsageExtension ekuExt = ekuExts.Current;

                if (!ekuExt.Critical)
                {
                    return(false);
                }

                bool hasPurpose = false;

                foreach (Oid oid in ekuExt.EnhancedKeyUsages)
                {
                    if (oid.Value == Oids.TimeStampingPurpose)
                    {
                        hasPurpose = true;
                        break;
                    }
                }

                if (!hasPurpose)
                {
                    return(false);
                }

                if (ekuExts.MoveNext())
                {
                    return(false);
                }
            }

            try
            {
                signer.CheckSignature(new X509Certificate2Collection(tsaCertificate), true);
                return(true);
            }
            catch (CryptographicException)
            {
                return(false);
            }
        }