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); } } }
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); } }